Java 动态代理:动态生成代理对象的技巧
一、动态代理的概念
Java动态代理允许在运行时动态创建实现一个或多个接口的代理类,而无需在编译时静态定义代理类的字节码。
二、动态代理的使用场景
动态代理适用于需要在运行时动态拦截方法调用的场景,如日志记录、事务处理、访问控制等。
三、使用java.lang.reflect.Proxy
类
Java通过Proxy
类和InvocationHandler
接口实现动态代理。
import cn.juwatech.proxy.MyInvocationHandler;
import java.lang.reflect.Proxy;
interface Service {
void performService();
}
class ServiceImpl implements Service {
public void performService() {
System.out.println("Performing service.");
}
}
public class DynamicProxyExample {
public static void main(String[] args) {
Service realService = new ServiceImpl();
InvocationHandler handler = new MyInvocationHandler(realService);
Service proxyInstance = (Service) Proxy.newProxyInstance(
Service.class.getClassLoader(),
new Class<?>[]{Service.class},
handler);
proxyInstance.performService();
}
}
四、自定义InvocationHandler
自定义InvocationHandler
可以控制代理对象的方法调用逻辑。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyInvocationHandler implements InvocationHandler {
private Object proxiedObject;
public MyInvocationHandler(Object proxiedObject) {
this.proxiedObject = proxiedObject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Before method: " + method.getName());
Object result = method.invoke(proxiedObject, args);
System.out.println("After method: " + method.getName());
return result;
}
}
五、动态代理与静态代理的比较
与静态代理相比,动态代理不需要为每个代理编写单独的代理类。
六、动态代理的局限性
动态代理要求被代理的类实现一个或多个接口,对于没有接口的类则不适用。
七、CGLIB代理
CGLIB(Code Generation Library)是一个强大的高性能代码生成库,可以用于创建不实现接口的类的代理。
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.ReflectUtils;
public class CglibProxyExample {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(ServiceImpl.class);
enhancer.setCallback((MethodInterceptor) (o, method, objects, methodProxy) -> {
System.out.println("Before method: " + method.getName());
Object result = methodProxy.invokeSuper(o, objects);
System.out.println("After method: " + method.getName());
return result;
});
ServiceImpl proxyInstance = (ServiceImpl) enhancer.create();
proxyInstance.performService();
}
}
八、动态代理与AOP
动态代理是实现面向切面编程(AOP)的一种技术手段。
九、动态代理的性能考虑
虽然动态代理非常灵活,但也可能带来性能开销,需要根据实际情况权衡。
十、动态代理在Java框架中的应用
许多Java框架,如Spring AOP、Hibernate,都使用了动态代理技术。