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机制实现,通过生成业务类的子类作为代理类。
优点:没有接口也能实现动态代理,采用字节码增强技术,性能也不错。
缺点:相对底层,难以理解。

浙公网安备 33010602011771号