`
wanxiaotao12
  • 浏览: 477372 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Spring 中JDKProxy和CGlibProxy的区别

 
阅读更多

Spring 实现AOP是依赖JDK动态代理和CGLIB代理实现的。

JDK动态代理和CGLIB字节码生成的区别?


 * JDK动态代理只能对实现了接口的类生成代理,而不能针对类
 * CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法
   因为是继承,所以该类或方法最好不要声明成final 

 

 

下面就看看怎么用JDK、CGLib的方式实现动态代理

 

首先先看下

 

UserManager接口

  1. package com.macower.spring.proxy;  
  2.   
  3. public interface UserManager {  
  4.     public void addUser(String id, String password);  
  5.     public void delUser(String id);  
  6. }  

 

 

接下来是其实现类  UserManagerImpl

  1. package com.macower.spring.proxy;  
  2.   
  3. public class UserManagerImpl implements UserManager {  
  4.   
  5.     public void addUser(String id, String password) {  
  6.         System.out.println(".: 掉用了UserManagerImpl.addUser()方法! ");  
  7.   
  8.     }  
  9.   
  10.     public void delUser(String id) {  
  11.         System.out.println(".: 掉用了UserManagerImpl.delUser()方法! ");  
  12.   
  13.     }  
  14. }  

 

 

 

JDK动态代理类

  1. package com.macower.spring.proxy;  
  2. import java.lang.reflect.InvocationHandler;  
  3. import java.lang.reflect.Method;  
  4. import java.lang.reflect.Proxy;  
  5. /** 
  6.  *  
  7.  * JDK动态代理类 
  8.  * @author Macower 
  9.  * 
  10.  */  
  11. public class JDKProxy implements InvocationHandler {  
  12.   
  13.     private Object targetObject;//需要代理的目标对象   
  14.   
  15.     public Object newProxy(Object targetObject) {//将目标对象传入进行代理   
  16.         this.targetObject = targetObject;   
  17.         return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),  
  18.                 targetObject.getClass().getInterfaces(), 
  19.                 this);
  20. //第三个参数是指用不用哪一个反射处理类
  21. 返回代理对象, 当代理对象执行某一方法时, 就会调用反射处理类的invoke方法   
  22.    
  23. }  
  24.     //实现InvocationHandler接口,实现其invoke方法
  25.     public Object invoke(Object proxy, Method method, Object[] args)//invoke方法   
  26.             throws Throwable {  
  27.         checkPopedom();//一般我们进行逻辑处理的函数比如这个地方是模拟检查权限   
  28.         Object ret = null;      // 设置方法的返回值   
  29.         ret  = method.invoke(targetObject, args);       //调用invoke方法,ret存储该方法的返回值   
  30.         return ret;  
  31.     }  
  32.   
  33.     private void checkPopedom() {//模拟检查权限的例子   
  34.         System.out.println(".:检查权限  checkPopedom()!");  
  35.     }  
  36. }  

 

 

CGLibProxy动态代理类

  1. package com.macower.spring.proxy;  
  2.   
  3. import java.lang.reflect.Method;  
  4.   
  5. import net.sf.cglib.proxy.Enhancer;  
  6. import net.sf.cglib.proxy.MethodInterceptor;  
  7. import net.sf.cglib.proxy.MethodProxy;  
  8.   
  9. /** 
  10.  * CGLibProxy动态代理类的实例 
  11.  *  
  12.  * @author Macower 
  13.  *  
  14.  */  
  15. public class CGLibProxy implements MethodInterceptor {  
  16.   
  17.     private Object targetObject;// CGLib需要代理的目标对象   
  18.   
  19.     public Object createProxyObject(Object obj) {  
  20.         this.targetObject = obj;  
  21.         Enhancer enhancer = new Enhancer();  
  22.         enhancer.setSuperclass(obj.getClass());  
  23.         enhancer.setCallback(this);  
  24.         Object proxyObj = enhancer.create();  
  25.         return proxyObj;// 返回代理对象   
  26.     }  
  27.   
  28.     public Object intercept(Object proxy, Method method, Object[] args,  
  29.             MethodProxy methodProxy) throws Throwable {  
  30.         Object obj = null;  
  31.         if ("addUser".equals(method.getName())) {// 过滤方法   
  32.             checkPopedom();// 检查权限   
  33.         }  
  34.         obj = method.invoke(targetObject, args);  
  35.         return obj;  
  36.     }  
  37.   
  38.     private void checkPopedom() {  
  39.         System.out.println(".:检查权限  checkPopedom()!");  
  40.     }  
  41. }  

 

 

 

下面来测试下

  1. package com.macower.spring.proxy;  
  2.   
  3. public class Client {  
  4.   
  5.     public static void main(String[] args) {  
  6.   
  7.         UserManager userManager = (UserManager) new CGLibProxy()  
  8.                 .createProxyObject(new UserManagerImpl());  
  9.         System.out.println("-----------CGLibProxy-------------");  
  10.         userManager.addUser("Macower""root");  
  11.         System.out.println("-----------JDKProxy-------------");  
  12.         JDKProxy jdkPrpxy = new JDKProxy();  
  13.         UserManager userManagerJDK = (UserManager) jdkPrpxy  
  14.                 .newProxy(new UserManagerImpl());  
  15.         userManagerJDK.addUser("Macower""root");  
  16.     }  
  17.   
  18. }  

 

 

 

执行结果是:

  1. -----------CGLibProxy-------------  
  2. .:检查权限  checkPopedom()!  
  3. .: 掉用了UserManagerImpl.addUser()方法!   
  4. -----------JDKProxy-------------  
  5. .:检查权限  checkPopedom()!  
  6. .: 掉用了UserManagerImpl.addUser()方法!   

 

 

 

 

JDK代理是不需要以来第三方的库,只要要JDK环境就可以进行代理,它有几个要求

 

* 实现InvocationHandler接口, 实现invoke方法
* 使用Proxy.newProxyInstance产生代理对象,代理类调用方法时, 自动调用Invocationhandler实现类的invoke方法

* 被代理的对象必须是某个接口的实现(因为返回的代码对象的类型是接口类型)

 

CGLib 必须依赖于CGLib的类库,但是它需要类来实现任何接口代理的是指定的类生成一个子类,覆盖其中的方法,是一种继承

 

但是针对接口编程的环境下推荐使用JDK的代理

在Hibernate中的拦截器其实现考虑到不需要其他接口的条件Hibernate中的相关代理采用的是CGLib来执行

 

 

分享到:
评论

相关推荐

    Spring_0300_JDKProxy

    标题"Spring_0300_JDKProxy"暗示我们将讨论Spring如何使用JDK的Proxy类来实现动态代理。在Spring中,`org.springframework.aop.framework.ProxyFactoryBean`或`org.springframework.aop.framework.ProxyFactory`可以...

    spring对应jdk1.8的jar包

    然而,随着Java版本的升级,有时候不同版本的Spring和JDK之间可能会出现兼容性问题。在本例中,我们讨论的是Spring 3.2.0版本与JDK 1.8之间的冲突。 Spring 3.2.0发布于2012年,那时JDK 1.8尚未推出(JDK 1.8在2014...

    spring5.0和4.2.0 jdk8和jdk7 对应的版本

    Spring 5.0和4.2.0是两个重要的版本,分别对应不同的Java Development Kit (JDK) 版本,即JDK 8和JDK 7。在选择Spring版本时,与所使用的JDK兼容性是关键因素。 首先,让我们详细了解一下Spring 4.2.0。这个版本是...

    Aop jdk proxy实现小例子

    这个小例子适合初学者理解AOP和JDK Proxy的基本用法,对于经验丰富的开发者来说,可能更倾向于使用Spring AOP或其他高级AOP框架,它们提供了更为强大和灵活的特性。但无论如何,理解JDK Proxy的基本原理对掌握AOP...

    Spring框架中JDK动态代理和cglib动态代理

    Spring 框架中 JDK 动态代理和 CGLIB 动态代理是 Spring AOP 中一个非常重要的知识点。Spring AOP 框架会根据实际情况选择使用 JDK 的动态代理还是 CGLIB 的动态代理。 JDK 动态代理是 Java 自带的动态代理机制,它...

    spring jdk动态代理

    Spring AOP中的JDK动态代理与上述示例类似,只是Spring会自动处理代理对象的创建和`InvocationHandler`的设置。Spring通过`DefaultAopProxyFactory`和`JdkDynamicAopProxy`类来实现这一过程。在配置了AOP代理后,当...

    spring4.2.0对应jdk1.8spring,springMVC所有依赖包以及文档

    在JavaWeb开发中,Spring框架是一个至关重要的组件,它提供了丰富的功能来简化应用程序的构建,尤其是在服务层和表现层的整合上。Spring 4.2.0是该框架的一个稳定版本,它支持Java Development Kit(JDK)1.8,这...

    spring3兼容jdk1.8

    低版本spring兼容高版本jdk,原有项目升级jdk和tomcat

    spring2.5+JDK1.8 版本报错的解决办法(修改后jar)

    原来这个工程的spring是2.5,网上说spring2.5必须要求JDK1.5以上版本,但不能兼容1.8。 没道理会这样吧? 原来spring-2.5.5.jar有一个检查JDK版本号的类,编码质量略低,导致1.8被误认为未达到“JDK1.5以上版本”...

    spring2.5.5+JDK1.8 版本报错的解决办法(修改后jar)

    org.springframework.core.JdkVersion 于是找到一个spring-core-3.x.RELEASE.jar,用其中的JdkVersion这个类替换spring-2.5.5.jar对应class,问题解决! 注意:别用spring-core-4.x.RELEASE.jar,JdkVersion....

    spring练习项目.7z

    proxy,jdkproxy-transaction,jdkproxy-salary,day02-itheima11-spring-08-cglibproxy,day02-itheima11-spring-09-aop.xml,day02-itheima11-spring-10-aop.xml.advice,day02-itheima11-spring-11-aop.xml.exception等...

    spring proxy代理模仿

    在Spring AOP中,有两种类型的代理:JDK动态代理和CGLIB代理。 1. JDK动态代理:当目标对象实现了至少一个接口时,Spring会使用JDK的Proxy类来创建代理对象。代理对象同样实现了目标对象的所有接口,因此可以通过...

    熟练使用spring和jdk的注解类-百度网盘地址.txt

    熟练使用spring和jdk的注解类,优质视频教程,学完后受益良多

    spring+jdk定时器

    JDK定时器适合简单的定时需求,而Spring的`@Scheduled`注解适用于大多数场景,Quartz则在需要更高级特性和复杂调度时成为首选。理解这些工具的工作原理和使用方法,将有助于在实际开发中有效地实现和管理定时任务。

    spring aop支持jdk1.7的jar

    这个版本1.7.4的jar文件包含了AspectJ编译器(ajc)和其他必要的工具,使得开发者能够在Spring环境中使用AspectJ表达式来定义切入点和通知。 aspectjweaver-1.7.4.jar是AspectJ运行时的一部分,主要负责在应用程序...

    Spring示例_Printer_Spring_AOP_Spring_Proxy

    在本示例中,"Spring示例_Printer_Spring_AOP_Spring_Proxy" 主要关注的是Spring框架中的核心概念,特别是AOP(面向切面编程)和代理模式的应用。让我们深入探讨这些知识点。 首先,Spring框架是Java开发中最常用的...

    过滤器 spring4.1+jdk1.7版本

    总结,这个"过滤器 spring4.1+jdk1.7版本"的压缩包提供了一个学习和实践Spring Filter和Interceptor的平台,通过分析和运行其中的代码,开发者可以深入理解这两种机制在Java Web开发中的应用和重要性。同时,对于...

    基于Jdk11 + SpringCloud + SpringBoot 开发的微服务中后台快速开发平台

    lamp-cloud 基于Jdk11 + SpringCloud + SpringBoot 开发的微服务中后台快速开发平台,专注于多租户(SaaS架构)解决方案,亦可作为普通项目(非SaaS架构)的基础开发框架使用,目前已实现插拔式数据库隔离、SCHEMA隔离...

    兼容jdk1.8的spring.jar包

    该jar包兼容了jdk1.3到1.8,可以放心使用。

    兼容jdk1.8的spring2.5.6.jar

    网上能找到同样的资源,但是兼容了jdk1.8,在jdk1.6下运行就会报错了。此jar包 兼容jdk1.6、jdk1.7、jdk1.8,仅仅修改了org.springframework.core.JdkVersion这个类,请放心使用。

Global site tag (gtag.js) - Google Analytics