Ответ
Да, можно, используя стандартные средства Java или сторонние библиотеки. Выбор зависит от того, реализует ли целевой класс интерфейсы.
1. Для классов, реализующих интерфейсы: java.lang.reflect.Proxy
Это стандартный API Java, который создает динамический прокси на лету.
import java.lang.reflect.Proxy;
import java.lang.reflect.InvocationHandler;
interface Service {
void execute();
}
class RealService implements Service {
public void execute() {
System.out.println("Выполняю реальную работу.");
}
}
InvocationHandler handler = (proxy, method, args) -> {
System.out.println("Перед вызовом метода: " + method.getName());
Object result = method.invoke(new RealService(), args);
System.out.println("После вызова метода: " + method.getName());
return result;
};
Service proxyInstance = (Service) Proxy.newProxyInstance(
Service.class.getClassLoader(),
new Class[]{Service.class},
handler
);
proxyInstance.execute();
2. Для классов без интерфейсов: CGLIB или ByteBuddy Эти библиотеки создают прокси путем наследования от целевого класса. Пример с CGLIB:
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
class SimpleService {
public void process() {
System.out.println("Обработка...");
}
}
MethodInterceptor interceptor = (obj, method, args, proxy) -> {
System.out.println("Перехват вызова.");
return proxy.invokeSuper(obj, args);
};
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(SimpleService.class);
enhancer.setCallback(interceptor);
SimpleService proxy = (SimpleService) enhancer.create();
proxy.process();
Ключевые ограничения:
java.lang.reflect.Proxyработает только с интерфейсами.- CGLIB требует, чтобы класс имел конструктор по умолчанию (без аргументов).
- Любой прокси добавляет накладные расходы на рефлексию и создание объектов.