Java的动态代理是一种在运行时动态创建代理对象的机制,主要用于在不修改原始类的情况下对方法调用进行拦截和增强。
Java动态代理主要分为两种类型:
- 基于接口的代理(JDK动态代理):这种类型的代理要求目标对象必须实现至少一个接口。Java动态代理会创建一个实现了相同接口的代理类,然后再运行时动态生成该类的实例。这种代理的实现核心是 java.lang.reflect.Proxy 类和 java.lang.reflect.InvocationHandler 接口。每一个动态代理类都必须实现 InvocationHandler 接口,并且每个代理类的实例都关联到一个handler。当通过代理对象调用一个方法时,这个方法的调用就会被转发为由 InvocationHandler 接口的 invoke() 方法来进行调用。
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; // 定义接口 interface UserService { void addUser(String userName); } // 实现接口 class UserServiceImpl implements UserService { @Override public void addUser(String userName) { System.out.println("User added: " + userName); } } // 实现 InvocationHandler class DynamicProxyHandler implements InvocationHandler { private final Object target; public DynamicProxyHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Before invoking method: " + method.getName()); Object result = method.invoke(target, args); System.out.println("After invoking method: " + method.getName()); return result; } } // 测试动态代理 public class DynamicProxyExample { public static void main(String[] args) { UserService userService = new UserServiceImpl(); InvocationHandler handler = new DynamicProxyHandler(userService); // 创建代理对象 UserService proxy = (UserService) Proxy.newProxyInstance( userService.getClass().getClassLoader(), userService.getClass().getInterfaces(), handler ); proxy.addUser("Alice"); } }
- 基于类的代理(CGLIB动态代理):CGLIB(Code Generation Library)是一个强大的高性能的代码生成库,它可以在运行时动态生成一个目标类的子类。CGLIB代理不需要目标类实现接口,而是通过继承的方式创建代理类。因此,如果目标对象没有实现任何接口,可以使用CGLIB来创建动态代理。
import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; // 被代理的类 class UserService { public void addUser(String userName) { System.out.println("User added: " + userName); } } // CGLib动态代理 class CglibProxy implements MethodInterceptor { @Override public Object intercept(Object obj, java.lang.reflect.Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("Before invoking method: " + method.getName()); Object result = proxy.invokeSuper(obj, args); System.out.println("After invoking method: " + method.getName()); return result; } } // 测试CGLib动态代理 public class CglibProxyExample { public static void main(String[] args) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(UserService.class); enhancer.setCallback(new CglibProxy()); // 创建代理对象 UserService proxy = (UserService) enhancer.create(); proxy.addUser("Bob"); } }
动态代理的优缺点:
优点:
- 解耦:代理逻辑与业务逻辑分离,易于管理和扩展。
- 灵活性:可以在运行时灵活地改变代理逻辑,例如在不同的环境中可以选择不同的处理方式。
- 增强功能:可以在不修改目标类的情况下增强其功能。
缺点:
- 性能开销:由于反射的使用,动态代理相较于静态代理性能较低。
- 调式困难:由于动态动态代理在运行时生成代理对象,跟踪和调试时可能会导致困难。调用栈中会涉及到代理类,可能使得问题的根源不易查找。
总结:
动态代理在Java中提供了一种灵活的方式来控制方法调用,广泛应用于各种场景,如AOP(面向切面编程)、框架开发等。
标签:Java,Object,代理,public,proxy,动态,method From: https://blog.csdn.net/weixin_73526362/article/details/143840748