Java如何实现动态代理模式
更新时间:2023-11-08动态代理模式介绍
动态代理是一种设计模式,它允许我们在运行时创建代理对象,使其代表另一个对象,并在代理对象中添加额外的功能。这样,我们可以在不修改原始对象代码的情况下,通过代理对象来提供额外的行为。
Java中的动态代理
Java提供了两种方式实现动态代理:基于接口的动态代理和基于类的动态代理。
基于接口的动态代理
基于接口的动态代理是通过Proxy类和InvocationHandler接口实现的。Proxy类提供了一个静态方法newProxyInstance()来创建代理对象。这个方法接收三个参数:ClassLoader,代理类实现的接口列表,和InvocationHandler对象。
public interface Subject { void doSomething(); } public class RealSubject implements Subject { public void doSomething() { System.out.println("RealSubject doSomething"); } } public class ProxyHandler implements InvocationHandler { private Object realObject; public ProxyHandler(Object realObject) { this.realObject = realObject; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 添加额外的逻辑 System.out.println("Before doSomething"); Object result = method.invoke(realObject, args); System.out.println("After doSomething"); return result; } } public class Main { public static void main(String[] args) { Subject realSubject = new RealSubject(); Subject proxySubject = (Subject) Proxy.newProxyInstance( realSubject.getClass().getClassLoader(), realSubject.getClass().getInterfaces(), new ProxyHandler(realSubject)); proxySubject.doSomething(); } }
基于类的动态代理
基于类的动态代理是通过CGLIB库实现的。CGLIB是一个强大的第三方库,它允许在运行时通过生成字节码来创建类的子类作为代理对象。
public class RealSubject { public void doSomething() { System.out.println("RealSubject doSomething"); } } public class ProxyInterceptor implements MethodInterceptor { public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { // 添加额外的逻辑 System.out.println("Before doSomething"); Object result = proxy.invokeSuper(obj, args); System.out.println("After doSomething"); return result; } } public class Main { public static void main(String[] args) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(RealSubject.class); enhancer.setCallback(new ProxyInterceptor()); RealSubject proxySubject = (RealSubject) enhancer.create(); proxySubject.doSomething(); } }
总结
通过Java的动态代理模式,我们可以在运行时动态地创建代理对象,并在代理对象中添加额外的逻辑。基于接口的动态代理通过Proxy类和InvocationHandler接口实现,而基于类的动态代理则通过CGLIB库实现。动态代理模式在实际应用中有广泛的应用,例如AOP切面编程、远程方法调用、事务管理等。