← Назад к вопросам

Создаешь ли новый класс при проксировании объекта

1.0 Junior🔥 121 комментариев
#ООП#Основы Java

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Проксирование объектов и создание новых классов

Да, при проксировании объекта динамически создаётся новый класс, который наследует интерфейсы оригинального объекта и перехватывает вызовы методов.

Как это работает

1. Java Dynamic Proxy (java.lang.reflect.Proxy)

Это встроенный в Java механизм для создания proxy-объектов. Когда вы вызываете Proxy.newProxyInstance(), JVM динамически генерирует новый класс, который:

  • Реализует все указанные интерфейсы
  • Перехватывает все вызовы методов через InvocationHandler
  • Передаёт вызовы оригинальному объекту
public interface UserService {
    String getUser(int id);
    void saveUser(String name);
}

public class UserServiceImpl implements UserService {
    @Override
    public String getUser(int id) {
        return "User " + id;
    }
    
    @Override
    public void saveUser(String name) {
        System.out.println("Saving: " + name);
    }
}

// Создание proxy
UserService original = new UserServiceImpl();
UserService proxy = (UserService) Proxy.newProxyInstance(
    UserService.class.getClassLoader(),
    new Class[]{UserService.class},
    (Object proxyObj, Method method, Object[] args) -> {
        System.out.println("[LOG] Вызов метода: " + method.getName());
        long start = System.currentTimeMillis();
        
        Object result = method.invoke(original, args);
        
        long duration = System.currentTimeMillis() - start;
        System.out.println("[LOG] Выполнено за " + duration + "ms");
        return result;
    }
);

proxy.getUser(1);  // Вывод: [LOG] Вызов метода: getUser ...
proxy.saveUser("John");  // Вывод: [LOG] Вызов метода: saveUser ...

2. CGLib - Proxy по классам

В отличие от Dynamic Proxy, которая работает только с интерфейсами, CGLib может проксировать конкретные классы через наследование и создание подклассов:

public class UserService {
    public String getUser(int id) {
        return "User " + id;
    }
}

// CGLib создаёт подкласс UserService
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserService.class);
enhancer.setCallback((MethodInterceptor) (obj, method, args, proxy) -> {
    System.out.println("[LOG] Вызов: " + method.getName());
    return proxy.invokeSuper(obj, args);
});

UserService proxyService = (UserService) enhancer.create();
proxyService.getUser(1);

Отличия подходов

АспектDynamic ProxyCGLib
Что проксируетИнтерфейсыКлассы
Встроена в JDKДаНет (отдельная библиотека)
Переопределение final методовНетДа
ПроизводительностьВышеНиже (генерация bytecode)

Практическое применение

Spring AOP использует обе технологии:

  • По умолчанию Dynamic Proxy (если есть интерфейсы)
  • CGLib (если класс без интерфейсов)
@Aspect
@Component
public class LoggingAspect {
    @Around("execution(* com.example.service.*.*(..))") 
    public Object log(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("Before: " + pjp.getSignature());
        Object result = pjp.proceed();
        System.out.println("After: " + pjp.getSignature());
        return result;
    }
}

Ключевой момент

Прокси — это обёртка над оригинальным объектом, которая не изменяет сам оригинальный класс, а создаёт новый класс (либо через реализацию интерфейсов, либо через наследование), который имитирует его поведение и добавляет дополнительную логику перед/после вызовов методов.

Создаешь ли новый класс при проксировании объекта | PrepBro