关于JDK动态代理的实现讲解,jdk动态讲解
关于JDK动态代理的实现讲解,jdk动态讲解
众所周知,Spring的AOP是基于动态代理实现的,下面是对其中的一种,JDK动态代理实现的一些理解
一、当我们要代理一个对象时,如TargetImpl对象,操作如下
InvocationHandler handler=new BusinessHandler(new TargetImpl());
Target proxy=(Target)Proxy.newProxyInstance(TargetImpl.class.getClassLoader(), new Class[]{Target.class}, handler);
上面的proxy继承了目标接口,所以跟Target接口一样可以调用相同的方法,达到代理的目的
二、其中的InvocationHandler(调用处理器)需要自己定义,毕竟是为了代理目标类的方法,所以这些多出来的逻辑操作应该在它里面的invoke方法中定义,如
public class BusinessHandler implements InvocationHandler { private Object object; public BusinessHandler(Object object) { this.object=object; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (method.getName().equals("output1")) { System.out.println("before calling output1"); method.invoke(object, args);//调用这个对象的方法 System.out.println("after calling output1"); } else if (method.getName().equals("output2")) { System.out.println("before calling output2"); method.invoke(object, args); System.out.println("after calling output2"); } return null;//这里return的是proxy.output1()/output2() } }
为什么要在这个handler里面定义一个目标对象?因为在invoke方法中需要利用反射调用到该对象方法,这样也就知道了为什么在handler实例化时要使用以目标对象为入参的构造方法,对invoke方法的入参
Object proxy, Method method, Object[] args 的理解可以参考到ProxyGenerator所生成的代理类
三、生成的代理类$Proxy0,大致结构如下
public class $Proxy extends Proxy implements Target{ Method m0,m1,m2,m3 ,m4; public void output1( ){ this.h.invoke(this,m3,(Object[ ])null); }public void output2( ){ this.h.invoke(this,m4,(Object[ ])null); }}
从中可以发现,生成的代理类中包含一个个Method对象,这正是目标对象的方法,当我们调用该代理类的目标对象方法,如
proxy.output1( )时,实际上会调用到第二点中自己编写的handler的invoke方法,该方法涵盖了所有目标对象方法格式,
@Override public Object invoke(Object proxy, Method method, Object[] args)
如返回值Object,当被代理的方法返回值为void时,在代理类中的方法则为直接调用,如上红字,否则为return this.h.invoke...
用户点评