jdk动态代理与cglib代理、spring Aop代理原理-代理使用浅析
2017-04-27 10:08
555 查看
原创声明:本博客来源为本人原创作品,绝非他处摘取,转摘请联系博主
代理(proxy)的定义:为某对象提供代理服务,拥有操作代理对象的功能,在某些情况下,当客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
动态代理实现主要有2种形式,主要分为:
1.jdk动态代理:
1)原理:是根据类加载器和接口创建代理类(此代理类是接口的实现类,所以必须使用接口 面向接口生成代理,位于java.lang.reflect包下)
2)实现方式:
1. 通过实现InvocationHandler接口创建自己的调用处理器 IvocationHandler handler = new InvocationHandlerImpl(…);
2. 通过为Proxy类指定ClassLoader对象和一组interface创建动态代理类Class clazz = Proxy.getProxyClass(classLoader,new Class[]{…});
3. 通过反射机制获取动态代理类的构造函数,其参数类型是调用处理器接口类型Constructor constructor = clazz.getConstructor(new Class[]{InvocationHandler.class});
4. 通过构造函数创建代理类实例,此时需将调用处理器对象作为参数被传入Interface Proxy = (Interface)constructor.newInstance(new Object[] (handler));
2~4步骤可合并
3)不足点:jdk动态代理,必须是面向接口,目标业务类必须实现接口
2.CGLIB代理
1.原理:利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
2.实现方法:
3.注意点:被代理目标不是是final修饰的类(final修饰类不能被继承)
spring aop代理原理
1.注意点:
如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP
如果目标对象实现了接口,可以强制使用CGLIB实现AOP
如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换
2.强制把jdk代理转换成cglib代理
添加CGLIB库,SPRING_HOME/cglib/*.jar
在spring配置文件中加入<aop:aspectj-autoproxy proxy-target-class = "true" />
传统AOP有默认的实现代理机制,可不需要专门指定代理,如自定义代理对象,可在类生成的时候自动代理,自动代理的方式主要有2种,一种是基于Bean名称的自动代理BeanNameAutoProxyCreator,另外一种是基于切面信息的自动代理DefaultAdvisorAutoProxyCreator
spring mvc 使用DefaultAdvisorAutoProxyCreator实现自动代理 配置
spring mvc 使用BeanNameAutoProxyCreator自动代理配
代理(proxy)的定义:为某对象提供代理服务,拥有操作代理对象的功能,在某些情况下,当客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
动态代理实现主要有2种形式,主要分为:
1.jdk动态代理:
1)原理:是根据类加载器和接口创建代理类(此代理类是接口的实现类,所以必须使用接口 面向接口生成代理,位于java.lang.reflect包下)
2)实现方式:
1. 通过实现InvocationHandler接口创建自己的调用处理器 IvocationHandler handler = new InvocationHandlerImpl(…);
2. 通过为Proxy类指定ClassLoader对象和一组interface创建动态代理类Class clazz = Proxy.getProxyClass(classLoader,new Class[]{…});
3. 通过反射机制获取动态代理类的构造函数,其参数类型是调用处理器接口类型Constructor constructor = clazz.getConstructor(new Class[]{InvocationHandler.class});
4. 通过构造函数创建代理类实例,此时需将调用处理器对象作为参数被传入Interface Proxy = (Interface)constructor.newInstance(new Object[] (handler));
2~4步骤可合并
package proxy.jdkproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import org.junit.Test; public class JDKProxy{ //写法1 private Object targetObject;//代理目标 public Object CustomerProxy(Object obj) { targetObject = obj; return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(),new targetHandler()); } class targetHandler implements InvocationHandler{ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("开启事务..."); Object returnValue = method.invoke(targetObject, args);//回调被代理目标的方法userDaoImpl.add(); System.out.println("提交事务"); return returnValue; } } public static void main(String[] args) { JDKProxy jdkProxy = new JDKProxy(); Customer userDao = (Customer)jdkProxy.CustomerProxy(new CustomerImpl()); userDao.shopping(); } //写法2 @Test public void test1(){ Customer customer = new CustomerImpl(); Customer cus = (Customer) Proxy.newProxyInstance(customer.getClass().getClassLoader(), customer.getClass().getInterfaces(),new InvocationHandler(){ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub return method.invoke(proxy, args); } }); cus.shopping(); } }
3)不足点:jdk动态代理,必须是面向接口,目标业务类必须实现接口
2.CGLIB代理
1.原理:利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
2.实现方法:
package proxy.cglib; import java.lang.reflect.Method; import org.junit.Test; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import proxy.model.Customer; public class CGLIBProxy { //写法1 private Object targetObject; private Object createProxy(Object obj){ targetObject = obj; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(targetObject.getClass());//设置代理对象,父类,说明是继承,所有代理对象不能为final enhancer.setCallback(new MyHandler()); return enhancer.create();//创建代理 } class MyHandler implements MethodInterceptor{ @Override public Object intercept(Object arg0, Method method, Object[] args, MethodProxy arg3) throws Throwable { System.out.println("开启事务.."); Object returnValue = method.invoke(targetObject, args); System.out.println("提交事务...."); return returnValue; } } @Test public void test1() { CGLIBProxy cglibProxy = new CGLIBProxy(); Customer customer = (Customer)cglibProxy.createProxy(new Customer()); customer.eat(); } //写法2 @Test public void test2(){ Customer customer = new Customer(); Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(customer.getClass()); enhancer.setCallback(new MethodInterceptor() { @Override public Object intercept(Object proxy, Method method, Object[] args, MethodProxy arg3) throws Throwable { if(method.getName().equals("eat")){ System.out.println("customer的eat方法被拦截了。。。。"); Object invoke = method.invoke(proxy, args); System.out.println("真实方法拦截之后。。。。"); return invoke; } // 不拦截 return method.invoke(proxy, args); } }); Customer cus = (Customer) enhancer.create(); cus.eat(); } }
3.注意点:被代理目标不是是final修饰的类(final修饰类不能被继承)
spring aop代理原理
1.注意点:
如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP
如果目标对象实现了接口,可以强制使用CGLIB实现AOP
如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换
2.强制把jdk代理转换成cglib代理
添加CGLIB库,SPRING_HOME/cglib/*.jar
在spring配置文件中加入<aop:aspectj-autoproxy proxy-target-class = "true" />
传统AOP有默认的实现代理机制,可不需要专门指定代理,如自定义代理对象,可在类生成的时候自动代理,自动代理的方式主要有2种,一种是基于Bean名称的自动代理BeanNameAutoProxyCreator,另外一种是基于切面信息的自动代理DefaultAdvisorAutoProxyCreator
spring mvc 使用DefaultAdvisorAutoProxyCreator实现自动代理 配置
<!--定义一个表示声明使用自动代理的类 --> <bean id="autoProxyCreator" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/> <!-- 定义代理类(本示例为异常类) --> <bean id="exceptionHandler" class="com.kaizhi.platform.util.ExceptionHandler"/> <!-- 定义支持正则表达式的通知 --> <bean id="exceptionHandlerAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice"> <ref bean="exceptionHandler"/> </property> <property name="patterns"> <value>.save*.*</value>//正则匹配需要拦截的方法 </property> </bean>
spring mvc 使用BeanNameAutoProxyCreator自动代理配
<!-- 基于BeanNameAutoProxyCreator,Bean名称的自动代理 --> <!-- 定义代理类 --> <bean id="exceptionHandler" class="com.kaizhi.platform.util.ExceptionHandler"/> <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <!-- 拦截的业务bean --> <property name="beanNames" value="*adminFinanceService"/> <!-- 拦截的通知 --> <property name="interceptorNames" value="exceptionHandler"/> </bean>
相关文章推荐
- Spring aop 基于JDK动态代理和CGLIB代理的原理以及为什么JDK代理需要基于接口
- 做一个合格的程序猿之浅析Spring AOP源码(十三) jdk的动态代理和cglib的代理
- 浅析Spring AOP源码(十三) jdk的动态代理和cglib的代理
- 重温Spring之旅5——AOP代理对象、JDK动态代理、使用cglib生产代理
- java动态代理——JDK和CGLIB原理解析与使用
- 在Spring中,是如何实现 Aop 的,原理:动态代理+cglib 分步图解
- 【Spring AOP】【AspectJ】【CGLIB】【JDK动态代理】【JDK静态代理】区别
- Java JDK动态代理(AOP)的实现原理与使用详析
- 分析动态代理Java JDK 动态代理(AOP)使用及实现原理分析
- Java JDK 动态代理(AOP)使用及实现原理分析
- Spring中AOP实现的两种方式之JDK和cglib的动态代理
- Java JDK 动态代理(AOP)使用及实现原理分析
- spring对AOP的支持 JDK动态代理和CGLIB的区别
- Spring AOP详解 、 JDK动态代理、CGLib动态代理
- Spring(十)通过动态代理(JDK的Proxy)和cglib实现AOP技术
- 为什么SpringAOP使用JDK动态代理时好像没有代理Object.[equals()、hashCode()、toString()]这三个方法
- Spring学习总结(二)——静态代理、JDK与CGLIB动态代理、AOP+IoC
- spring(AOP)静态代理、JDK动态代理、cglib实现代理
- 静态代理、JDK动态代理、CGLIB动态代理、Spring实现AOP、IOC+AOP
- Java JDK 动态代理(AOP)使用及实现原理分析