`

Spring 中JDKProxy和CGlibProxy的区别 .

 
阅读更多

环境要求

 

 

spring对AOP的支持

*如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP
* 如果目标对象实现了接口,可以强制使用CGLIB实现AOP
*如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换


如何强制使用CGLIB实现AOP?
 * 添加CGLIB库,SPRING_HOME/cglib/*.jar
 * 在spring配置文件中加入<aop:aspectj-autoproxy proxy-target-class="true"/>
 
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(), this);//返回代理对象   
  19.     }  
  20.   
  21.     public Object invoke(Object proxy, Method method, Object[] args)//invoke方法   
  22.             throws Throwable {  
  23.         checkPopedom();//一般我们进行逻辑处理的函数比如这个地方是模拟检查权限   
  24.         Object ret = null;      // 设置方法的返回值   
  25.         ret  = method.invoke(targetObject, args);       //调用invoke方法,ret存储该方法的返回值   
  26.         return ret;  
  27.     }  
  28.   
  29.     private void checkPopedom() {//模拟检查权限的例子   
  30.         System.out.println(".:检查权限  checkPopedom()!");  
  31.     }  
  32. }  

 

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
* 使用Proxy.newProxyInstance产生代理对象

* 被代理的对象必须要实现接口

 

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

 

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

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

 

所以在是实际的开发当中,开发人员应该根据实际的需求来选择合适的代理工具。

分享到:
评论

相关推荐

    兼容jdk1.8的spring2.5.6.jar

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

    spring-plugin-core-2.0.0.RELEASE-API文档-中文版.zip

    赠送jar包:spring-plugin-core-2.0.0.RELEASE.jar; 赠送原API文档:spring-plugin-core-2.0.0.RELEASE-javadoc.jar;...人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。

    spring 3.2.4.RELEASE jar包

    spring 3.2.4 Realease 的所有jar包: spring-context-3.2.4.RELEASE.jar spring-core-3.2.4.RELEASE.jar spring-beans-3.2.4.RELEASE.jar spring-test-3.2.4.RELEASE.jar spring-web-3.2.4.RELEASE.jar spring-aop-...

    spring-framework-4.1.6.RELEASE.rar

    此压缩文件中包含spring的如下组件的doc,source,jar: spring-aop-4.1.6.RELEASE.jar spring-aspects-4.1.6.RELEASE.jar spring-beans-4.1.6.RELEASE.jar spring-context-4.1.6.RELEASE.jar spring-context-...

    spring-cglib-repack-3.2.5.jar,spring-objenesis-repack-2.6.jar

    标题中的"spring-cglib-repack-3.2.5.jar"和"spring-objenesis-repack-2.6.jar"是Spring框架在运行时依赖的两个关键库,它们主要涉及到动态代理和对象创建的优化。 1. **CGLIB(Code Generation Library)**: ...

    Spring源码缺失的spring-cglib-repack-3.2.6.jar和spring-objenesis-repack-2.6.jar

    在Spring框架中,`spring-cglib-repack-3.2.6.jar`和`spring-objenesis-repack-2.6.jar`是两个重要的依赖库,它们在Spring源码环境中扮演着不可或缺的角色。本文将详细介绍这两个库以及它们在Spring框架中的作用。 ...

    使用SpringCloud Zuul Proxy构建API网关.docx

    在本文中,我们将深入探讨如何使用 Spring Cloud Zuul Proxy 实现 API 网关,并分析其优点和缺点。 **为什么要使用 API 网关?** API 网关的主要目的是简化客户端与微服务之间的交互,隐藏后端复杂性。它提供了一个...

    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...

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

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

    spring-mock.jar

    Classes contained in spring-mock.jar: org.springframework.mock.jndi.ExpectedLookupTemplate.class org.springframework.mock.jndi.SimpleNamingContext.class org.springframework.mock.jndi....

    spring4.3.9jar包.zip

    (jdk1.8和spring4)\cglib-2.2.2.jar, 287192 , 2019-03-06 (jdk1.8和spring4)\commons-dbcp-1.2.2.jar, 121757 , 2019-03-06 (jdk1.8和spring4)\commons-logging-1.1.1.jar, 60686 , 2019-03-06 (jdk1.8和...

    Spring_0300_JDKProxy

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

    spring-data-commons-1.7.2.RELEASEspring-data-jpa-1.5.2.RELEASE-java datajpa

    Spring Data Commons 和 Spring Data JPA 是 Spring 框架中的两个关键模块,它们在 Java 应用开发中扮演着重要角色,特别是在数据访问层。这两个模块是基于 Java 的数据访问接口(JPA)来简化数据库操作,使得开发者...

    jdk7-Spring MVC核心包集合.rar

    jdk7SpringMVC 13个核心jar包大集合 包括 1.spring-aop-3.2.0.RELEASE.jar 2.spring-aspects-3.2.0.RELEASE.jar 3.spring-beans-3.2.0.RELEASE.jar 4.spring-context-3.2.0.RELEASE.jar 5.spring-context-support-...

    spring-aop.jar各个版本

    spring-aop-1.1.1.jar spring-aop-1.2.6.jar spring-aop-1.2.9.jar spring-aop-2.0.2.jar spring-aop-2.0.6.jar spring-aop-2.0.7.jar spring-aop-2.0.8.jar spring-aop-2.0.jar spring-aop-2.5.1.jar spring-aop-...

    spring4.3.16相关jar包打包下载

    本压缩包中的文件是Spring框架4.3.16版本的各个核心模块,这个版本是在JDK1.8环境下支持的。以下是这些模块的详细介绍: 1. **spring-context-4.3.16.RELEASE.jar**:这是Spring的核心上下文模块,它扩展了bean工厂...

    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等...

    spring3.0.5 所有jar文件

    包含spring 3.0.5的所有jar文件: org.springframework.aop-3.0.5.RELEASE.jar org.springframework.asm-3.0.5.RELEASE.jar org.springframework.aspects-3.0.5.RELEASE.jar org.springframework.beans-3.0.5.RELEASE...

    spring3.1 官方全部jar包

    spring3.1官方所有的jar包 org.springframework.aop-3.1.RELEASE.jar org.springframework.asm-3.1.RELEASE.jar org.springframework.aspects-3.1.RELEASE.jar org.springframework.beans-3.1.RELEASE.jar org....

    org.spring-framework-3.0.4. 所有jar

    org.springframework.aop-3.0.4.RELEASE.jar org.springframework.asm-3.0.4.RELEASE.jar org.springframework.aspects-3.0.4.RELEASE.jar org.springframework.beans-3.0.4.RELEASE.jar org.springframework....

Global site tag (gtag.js) - Google Analytics