AOP实现--JDK中的动态代理和cglib代理
2012-08-07 17:55
736 查看
java.lang.reflect Interface InvocationHandler
可参考http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/lang/reflect/InvocationHandler.htmlhttp://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/lang/reflect/Proxy.html
invocation是“调用”的意思。这个类可以让我们在JVM调用某个类的方法时动态的为些方法做些什么事.InvocationHandler接口把我们的代理对象和被代理对象解耦了.动态代理类可以对任何实现某一接口的类进行功能性的增强。
关于Method对象的invoke方法,根据java的反射机制可以获得某个对象的某个方法,也可以动态调用,假设已经获取了这个方法method.那么method.invoke(owner,args)就是动态调用,owner表示方法所属的对象,args为Object[]类型的方法参数。
接口InvocationHandler的方法
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
proxy:在其上调用方法的代理实例(Proxy类型的对象)。
method:对应于在代理实例上调用的接口方法的
Method实例。。
args:为方法的参数
package proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class DynProxy implements InvocationHandler{ private Object src;//被代理对象 //bind为自定义方法,将src绑定到某个代理中 //把当前对象(实现了InvocationHandler接口)传递给代理对象 //返回代理对象 public Object bind(Object src){ this.src=src; Object proxy=Proxy.newProxyInstance( src.getClass().getClassLoader(),//被代理对象的类加载器 src.getClass().getInterfaces(),//被代理对象实现的接口们,代理对象可以实现全部接口 this //当前对象(实现了InvocationHandler接口) 回调,拦截到一个方法后可以触发哪个类中的哪个方法。 ); //返回的是一个带有代理类的指定调用处理程序的代理实例,它由指定的类加载器定义,并实现指定的接口 return proxy; } //InvocationHandler接口方法 //src(目标对象)中的每个方法会被此方法送去JVM调用,也就是说,src的方法只能通过此方法调用 //此方法不能自己调用 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub System.out.println(method.getName()+"调用前"); Object result=method.invoke(src, args); return result; } public static void main(String[] args) { Login src=new Login(); //被代理对象 DynProxy dp=new DynProxy(); ILogin proxy=(ILogin)dp.bind(src); //返回代理对象 String username="tazi",password="123"; proxy.login(username, password); //在代理实例上调用接口方法 } }
代理对象实现了目标对象的接口,使用时要用接口来引用代理对象。
以上的代码改个名字更好理解:
package com.tazi.aop; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; //JDK方式的动态代理对象的创建工厂 public class JDKProxyFactory implements InvocationHandler{ private Object target;//目标对象 //创建代理对象的方法 //返回的是已经实现了目标对象所有接口的代理对象 public Object createProxy(Object target){ this.target=target; //以下前两个参数跟目标对象有关 //第三个参数是一个包含回调方法(invoke)的对象(实现InvocationHandler接口) return Proxy.newProxyInstance(target.getClass().getClassLoader() , target.getClass().getInterfaces(),this); } //当拦截到目标对象某个方法时的回调方法 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub System.out.println("方法执行前"); Object result=method.invoke(target, args); System.out.println("方法执行后"); return result; } }
测试用例:
package junit.test; import static org.junit.Assert.*; import org.junit.BeforeClass; import org.junit.Test; import com.tazi.aop.JDKProxyFactory; import com.tazi.aop.PersonService; import com.tazi.aop.PersonServiceBean; public class ProxyTest { private static JDKProxyFactory proxyFactory; @BeforeClass public static void setUpBeforeClass() throws Exception { proxyFactory=new JDKProxyFactory(); } @Test public void proxy() throws Exception { PersonService pService=(PersonService)proxyFactory.createProxy(new PersonServiceBean()); pService.save("xxx"); } }
CGLIB实现动态代理
但实际中情况会比较复杂,有可能目标对象没有实现接口。如果没有就不能创建代理对象。此时用到第三方的jar包来创建代理对象。cglib.jar。这时目标对象可以不实现接口。
cglib的实现方式是创建被代理对象的子类,这个子类覆盖了目标对象的所有的非final的所有方法。然后设置回调方法。
package com.tazi.aop; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class CglibProxyFactory implements MethodInterceptor{ private Object target; public Object createProxy(Object target){ this.target=target; Enhancer enhancer=new Enhancer(); enhancer.setSuperclass(target.getClass()); enhancer.setCallback(this); return enhancer.create(); } public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { System.out.println("方法执行前00"); Object result=method.invoke(target, args); System.out.println("方法执行后00"); return result; } }
相关文章推荐
- 通过CGLIB实现AOP的浅析(顺便简单对比了一下JDK的动态代理)
- AOP的底层实现-CGLIB动态代理和JDK动态代理
- AOP的底层实现-CGLIB动态代理和JDK动态代理
- AOP的底层实现-CGLIB动态代理和JDK动态代理
- AOP的底层实现-CGLIB动态代理和JDK动态代理
- spring对AOP的支持(JDK的动态代理实现AOP和CGLIB实现AOP)
- Spring(十)通过动态代理(JDK的Proxy)和cglib实现AOP技术
- spring(AOP)静态代理、JDK动态代理、cglib实现代理
- Java动态代理模式jdk和cglib的2种实现以及二者的区别(AOP面向切面的前奏)
- AOP的底层实现-CGLIB动态代理和JDK动态代理
- AOP的底层实现-CGLIB动态代理和JDK动态代理
- Spring AOP 代理实现的两种方式: JDK动态代理 和 Cglib框架动态代理
- AOP的底层实现-CGLIB动态代理和JDK动态代理
- AOP的底层实现-CGLIB动态代理和JDK动态代理
- AOP的底层实现-CGLIB动态代理和JDK动态代理
- Spring系列之 (十一):AOP实现方式:动态代理的两个方式(JDK和Cglib)
- Spring中AOP实现的两种方式之JDK和cglib的动态代理
- 利用动态代理实现AOP的简单示例(JDK和cglib分别实现)
- 静态代理、JDK动态代理、CGLIB动态代理、Spring实现AOP、IOC+AOP
- AOP的底层实现-CGLIB动态代理和JDK动态代理