Как в Java создается динамический Proxy и откуда он получает целевой объект?

«Как в Java создается динамический Proxy и откуда он получает целевой объект?» — вопрос из категории Spring, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Динамический прокси в Java создается с помощью java.lang.reflect.Proxy.newProxyInstance(). Прокси не наследует целевой класс, а реализует указанные интерфейсы, делегируя вызовы методов целевому объекту через InvocationHandler.

Параметры создания прокси:

  1. ClassLoader – для загрузки сгенерированного прокси-класса.
  2. Class<?>[] interfaces – массив интерфейсов, которые будет реализовывать прокси.
  3. InvocationHandler – обработчик, содержащий логику перехвата вызовов и ссылку на целевой объект.

Пример создания прокси с логированием:

interface Service {
    String process(String input);
}

class RealService implements Service {
    public String process(String input) { return "Processed: " + input; }
}

// 1. Создаем целевой объект
RealService target = new RealService();

// 2. Создаем Proxy
Service proxy = (Service) Proxy.newProxyInstance(
    Service.class.getClassLoader(),
    new Class[]{Service.class}, // Интерфейсы прокси
    new InvocationHandler() {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("Before: " + method.getName());
            // Делегируем вызов целевому объекту
            Object result = method.invoke(target, args);
            System.out.println("After: " + method.getName());
            return result;
        }
    }
);

// 3. Вызов идет через обработчик
proxy.process("test"); // Выведет: Before: process ... After: process

Ключевой момент: Ссылка на реальный объект (target) хранится и используется внутри пользовательской реализации InvocationHandler. Сам прокси-объект не содержит бизнес-логики.