JDK代理与CGlib代理
是什么
JDK代理:JDK代理是一种基于接口的动态代理,它实现了被代理对象所实现的接口,可以在运行时通过反射的方式来生成代理对象。
CGlib代理:CGlib代理是一种基于类的动态代理,它通过生成被代理对象的子类来实现代理。因此,被代理对象不需要实现接口。
为什么
使用代理模式的主要目的是为了在不修改原始类的前提下,为其添加一些额外的功能。在实际开发中,我们经常需要在业务逻辑执行前后,增加一些日志记录、权限校验、事务管理等功能,这些功能与业务逻辑关系不大,但是又必须加入到业务逻辑中。这时就可以使用代理模式来解决这个问题。
怎么用
JDK代理
- 定义一个接口:
public interface UserService {void save(User user);
}
- 实现接口:
public class UserServiceImpl implements UserService {@Overridepublic void save(User user) {System.out.println("保存用户信息:" + user);}
}
- 创建代理类,实现InvocationHandler接口:
public class UserServiceProxy implements InvocationHandler {// 被代理对象private Object target;public UserServiceProxy(Object target) {this.target = target;}@Overridepublic 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;}@Overridepublic 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}
执行方法后...