JDK代理与CGlib代理
是什么
JDK代理:JDK代理是一种基于接口的动态代理,它实现了被代理对象所实现的接口,可以在运行时通过反射的方式来生成代理对象。
CGlib代理:CGlib代理是一种基于类的动态代理,它通过生成被代理对象的子类来实现代理。因此,被代理对象不需要实现接口。
为什么
使用代理模式的主要目的是为了在不修改原始类的前提下,为其添加一些额外的功能。在实际开发中,我们经常需要在业务逻辑执行前后,增加一些日志记录、权限校验、事务管理等功能,这些功能与业务逻辑关系不大,但是又必须加入到业务逻辑中。这时就可以使用代理模式来解决这个问题。
怎么用
JDK代理
- 定义一个接口:
public interface UserService { void save(User user); }
- 实现接口:
public class UserServiceImpl implements UserService { @Override public void save(User user) { System.out.println("保存用户信息:" + user); } }
- 创建代理类,实现InvocationHandler接口:
public class UserServiceProxy implements InvocationHandler { // 被代理对象 private Object target; public UserServiceProxy(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("执行方法前..."); Object result = method.invoke(target, args); System.out.println("执行方法后..."); return result; } }
- 测试:
public static void main(String[] args) { UserServiceImpl userService = new UserServiceImpl(); UserService proxy = (UserService) Proxy.newProxyInstance(userService.getClass().getClassLoader(), userService.getClass().getInterfaces(), new UserServiceProxy(userService)); proxy.save(new User("Tom", 20)); }
输出结果:
执行方法前... 保存用户信息:User{name='Tom', age=20} 执行方法后...
CGlib代理
- 定义一个类:
public class UserService { public void save(User user) { System.out.println("保存用户信息:" + user); } }
- 创建代理类,继承MethodInterceptor接口:
public class UserServiceProxy implements MethodInterceptor { // 被代理对象 private Object target; public UserServiceProxy(Object target) { this.target = target; } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("执行方法前..."); Object result = method.invoke(target, args); System.out.println("执行方法后..."); return result; } }
- 测试:
public static void main(String[] args) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(UserService.class); enhancer.setCallback(new UserServiceProxy(new UserService())); UserService proxy = (UserService) enhancer.create(); proxy.save(new User("Tom", 20)); }
输出结果:
执行方法前... 保存用户信息:User{name='Tom', age=20} 执行方法后...