JDK动态代理和CGLIB动态代理

JDK动态代理实现

 

被代理类(需实现接口)

 1 public class UserServiceImp implements UserService{
 2     @Override
 3     public void doService() {
 4         System.out.println(this.getClass() + "doService");
 5         try {
 6             Thread.sleep(2000);
 7         } catch (InterruptedException e) {
 8             e.printStackTrace();
 9         }
10     }
11 }

 

扩展类

 1 public class LogHandler implements InvocationHandler {
 2 
 3     Object target;
 4 
 5     public LogHandler(Object target) {
 6         this.target = target;
 7     }
 8 
 9     @Override
10     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 重写invoke方法
11         before();
12         method.invoke(target, args);
13         after();
14         return null;
15     }
16     public void before() {
17         System.out.println("日志开始" + new Date(System.currentTimeMillis()));
18     }
19     public void after() {
20         System.out.println("日志结束" + new Date(System.currentTimeMillis()));
21     }
22 }

 

测试

 1 public class Test {
 2     public static void main(String[] args) {
 3         System.getProperties().setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
 4         UserServiceImp userService = new UserServiceImp(); // 创建被代理类对象
 5         LogHandler logHandler = new LogHandler(userService); // 创建扩展类对象,传入被代理类对象
 6         ClassLoader classLoader = userService.getClass().getClassLoader(); // 获取类加载器
 7         Class[] interfaces = userService.getClass().getInterfaces(); // 获取所有接口
 8         UserService proxy = (UserService) Proxy.newProxyInstance(classLoader, interfaces, logHandler); // 创建代理对象
 9         proxy.doService();
10     }
11 }

 

CGLIB动态代理实现

 

被代理类

 1 public class MyService {
 2 
 3     public void doService() {
 4         System.out.println(this.getClass() + "doService");
 5         try {
 6             Thread.sleep(2000);
 7         } catch (InterruptedException e) {
 8             e.printStackTrace();
 9         }
10     }
11 }

 

扩展类

 1 public class LogHandler implements MethodInterceptor {
 2     @Override
 3     public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
 4         before();
 5         methodProxy.invokeSuper(o, objects);
 6         after();
 7         return null;
 8     }
 9     public void before() {
10         System.out.println("日志开始" + new Date(System.currentTimeMillis()));
11     }
12     public void after() {
13         System.out.println("日志结束" + new Date(System.currentTimeMillis()));
14     }
15 }

 

测试

1 public class Test {
2     public static void main(String[] args) {
3         Enhancer enhancer = new Enhancer();
4         enhancer.setSuperclass(MyService.class);
5         enhancer.setCallback(new LogHandler());
6         MyService myService = (MyService)enhancer.create();
7         myService.doService();
8     }
9 }

 

JDK动态代理与CGLIB动态代理对比

 

JDK动态代理

 

基于Java反射机制实现,必须要实现了接口的业务类才能用这种方法生成代理。

优点:解决了静态代理中冗余的代理实现类问题。

缺点:代理类本身已经继承了Proxy,所以基于接口设计实现,如果业没有接口,会抛出异常。

 

CGLIB动态代理

 

基于ASM机制实现,通过生成业务类的子类作为代理类。

优点:没有接口也能实现动态代理,采用字节码增强技术,性能也不错。

缺点:相对底层,难以理解。

 

posted @ 2020-09-12 15:45  昆梧  阅读(169)  评论(0)    收藏  举报