当前位置: 移动技术网 > IT编程>开发语言>Java > JDK动态代理与CGLib动态代理的区别对比

JDK动态代理与CGLib动态代理的区别对比

2019年07月19日  | 移动技术网IT编程  | 我要评论

案例:

public interface forumservice {
 void removetopic(int topicid);
 void removeforum(int forumid);
}

对相关方法进行性能监控

public class forumserviceimpl implements forumservice {
 public void removetopic(int topicid) {
 // performancemonitor.begin("com.hand.proxy.forumserviceimpl.removetopic");
 system.out.println("模拟删除topic记录:" + topicid);
 try {
  thread.sleep(20);
 } catch (interruptedexception e) {
  e.printstacktrace();
 }
 // performancemonitor.end();
 }
 public void removeforum(int forumid) {
 // performancemonitor.begin("com.hand.proxy.forumserviceimpl.removeforum");
 system.out.println("模拟删除forum记录:" + forumid);
 try {
  thread.sleep(20);
 } catch (interruptedexception e) {
  e.printstacktrace();
 }
 // performancemonitor.end();
 }
}

性能监控实现类:

public class performancemonitor {
 // 通过一个threadlocal保存与调用线程相关的性能监视信息
 private static threadlocal<methodperformance> performancerecord = new threadlocal<methodperformance>();
 // 启动对某一目标方法的性能监视
 public static void begin(string method) {
 system.out.println("begin monitor...");
 methodperformance mp = new methodperformance(method);
 performancerecord.set(mp);
 }
 public static void end() {
 system.out.println("end monitor...");
 methodperformance mp = performancerecord.get();
 // 打印出方法性能监视的结果信息
 mp.printperformance();
 }
}

用于记录性能监控信息:

public class performancemonitor {
 // 通过一个threadlocal保存与调用线程相关的性能监视信息
 private static threadlocal<methodperformance> performancerecord = new threadlocal<methodperformance>();
 // 启动对某一目标方法的性能监视
 public static void begin(string method) {
 system.out.println("begin monitor...");
 methodperformance mp = new methodperformance(method);
 performancerecord.set(mp);
 }
 public static void end() {
 system.out.println("end monitor...");
 methodperformance mp = performancerecord.get();
 // 打印出方法性能监视的结果信息
 mp.printperformance();
 }
}

1、jdk动态代理

public class performancemonitor {
 // 通过一个threadlocal保存与调用线程相关的性能监视信息
 private static threadlocal<methodperformance> performancerecord = new threadlocal<methodperformance>();
 // 启动对某一目标方法的性能监视
 public static void begin(string method) {
 system.out.println("begin monitor...");
 methodperformance mp = new methodperformance(method);
 performancerecord.set(mp);
 }
 public static void end() {
 system.out.println("end monitor...");
 methodperformance mp = performancerecord.get();
 // 打印出方法性能监视的结果信息
 mp.printperformance();
 }
}
public class forumservicetest {
 @test
 public void proxy() {
 forumservice forumservice = new forumserviceimpl();
 performancehandler handler = new performancehandler(forumservice);
 forumservice proxy = (forumservice) proxy.newproxyinstance(forumservice.getclass().getclassloader(),
  forumservice.getclass().getinterfaces(), handler);
 proxy.removeforum(10);
 proxy.removetopic(1012);
 }
}

得到以下输出信息:

begin monitor...
模拟删除forum记录:10
end monitor...
com.hand.proxy.forumserviceimpl.removeforum花费21毫秒
begin monitor...
模拟删除topic记录:1012
end monitor...
com.hand.proxy.forumserviceimpl.removetopic花费21毫秒

2、cglib动态代理

 <!-- https://mvnrepository.com/artifact/cglib/cglib -->
 <dependency>
  <groupid>cglib</groupid>
  <artifactid>cglib</artifactid>
  <version>2.2.2</version>
 </dependency>
public class cglibproxy implements methodinterceptor {
 private enhancer enhancer = new enhancer();
 public object getproxy(class clazz) {
 enhancer.setsuperclass(clazz);
 enhancer.setcallback(this);
 return enhancer.create();
 }
 public object intercept(object obj, method method, object[] args, methodproxy proxy) throws throwable {
 performancemonitor.begin(obj.getclass().getname() + "." + method.getname());
 object result = proxy.invokesuper(obj, args);
 performancemonitor.end();
 return result;
 }
}
public class forumservicetest2 {
 @test
 public void proxy() {
 cglibproxy proxy = new cglibproxy();
 forumserviceimpl forumservice = (forumserviceimpl) proxy.getproxy(forumserviceimpl.class);
 forumservice.removeforum(10);
 forumservice.removetopic(1023);
 }
}

1)、jdk和cglib的区别

  • jdk动态代理只能对实现了接口的类生成代理,而不能针对类
  • cglib是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法(继承)

2)、spring在选择用jdk还是cglib的依据

  • 当bean实现接口时,spring就会用jdk的动态代理
  • 当bean没有实现接口时,spring使用cglib来实现
  • 可以强制使用cglib(在spring配置中加入<aop:aspectj-autoproxy proxy-target-class=“true”/>)

3)、jdk和cglib的性能对比

  • 使用cglib实现动态代理,cglib底层采用asm字节码生成框架,使用字节码技术生成代理类,在jdk1.6之前比使用java反射效率要高。唯一需要注意的是,cglib不能对声明为final的方法进行代理,因为cglib原理是动态生成被代理类的子类。
  • 在jdk1.6、jdk1.7、jdk1.8逐步对jdk动态代理优化之后,在调用次数较少的情况下,jdk代理效率高于cglib代理效率,只有当进行大量调用的时候,jdk1.6和jdk1.7比cglib代理效率低一点,但是到jdk1.8的时候,jdk代理效率高于cglib代理

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对移动技术网的支持。如果你想了解更多相关内容请查看下面相关链接

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网