JDK-动态代理_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > JDK-动态代理

JDK-动态代理

 2016/9/8 5:32:24  买切糕的猴子  程序员俱乐部  我要评论(0)
  • 摘要:1、JDK动态代理原理2、JDK动态代理模块结构一、JDK动态代理原理使用过JDK动态代理的都知道需要借助InvocationHandler和Proxy来实现代理,但是其原理是啥呢?最近研究了一下,这里做个小小的总结。先来看一个小的动态代理demo从demo类图可以看出,有一个接口UserDao和它的实现类,然后定义了我们的MyInvocationHandler,它必须实现JDK的InvocationHandler接口,通过invoke方法来对目标对象target添加增强的逻辑代码
  • 标签:jdk 代理
1、JDK动态代理原理 2、JDK动态代理模块结构 ? 一、JDK动态代理原理 ? ? ?使用过JDK动态代理的都知道需要借助InvocationHandler和Proxy来实现代理,但是其原理是啥呢?最近研究了一下,这里做个小小的总结。 ? ? ?先来看一个小的动态代理demo 从demo类图可以看出,有一个接口UserDao和它的实现类,然后定义了我们的MyInvocationHandler,它必须实现JDK的InvocationHandler接口,通过invoke方法来对目标对象target添加增强的逻辑代码,从而达到切面增强的目的。同时我们的MyInvocationHandler还提供了getProxy()方法用于获取目标对象的代理,最后通过调用代理对象的方法完成业务逻辑和增强逻辑。具体的代码如下: ? ??
class="java" name="code">public class ProxyTest {
	public static void main(String[] args) {
		UserDao dao = new UserDaoImpl();
		MyInvocationHandler h = new MyInvocationHandler(dao);
		UserDao proxy =  (UserDao) h.getProxy();
		proxy.add();
	}
}
?
public interface UserDao {
	void add();
}
?
public class UserDaoImpl implements UserDao{

	/* (non-Javadoc)
	 * @see example.spring.boot.demo.proxy.UserDao#add()
	 */
	@Override
	public void add() {
		System.out.println("add user-----------");
	}

}
?
public class MyInvocationHandler implements InvocationHandler{
	
	private Object target;
	
	/**
	 * @param target
	 */
	public MyInvocationHandler(Object target) {
		super();
		this.target = target;
	}



	/* (non-Javadoc)
	 * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("befor---------------");
		Object ret = method.invoke(target, args);
		System.out.println("after---------------");
		return ret;
	}
	
	
	public Object getProxy(){
		return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), target.getClass().getInterfaces(), this);
	}
}
? JDK动态代理流程如下图: 其实要想了解JDK动态代理的原理的关键就是理解它是如何动态生成代理对象,并且融合方法执行器的。下面来看看JDK的源码类图 ?????本文使用的是JDK1.8.45,1.8以后的动态和之前的有所不同,不同之处在于它使用了1.8才有的功能接口,但是并没有改变其原有的实现原理,只是用功能接口在外包了一层用于支持1.8的新特性。 ? ? ?JDK通过Proxy的newProxyInstance方法产生代理对象Class对象,然后通过Constructor的newInstance方法把代理对象和InvocationHanlder结合在一起,然后返回。我们把返回的对象反编译后可以看到方法里的实现改为了直接调用invocationHandler的invoke方法。 ? ? ?至于如何产生带对象的可以查看ProxyClassFactory的apply方法,它通过ProxyGenerator的generateProxyClass方法生成代理对象的字节码,然后经过调用本地方法 defineClass0加载字节码并生成代理对象的Class对象返回。

?

? ?值得一说的是这里会把已经生成过的代理对象缓存到WeakCache,相比之前的版本,在代理这块提高了一定的性能。
  • 大小: 38.3 KB
  • 大小: 44.7 KB
  • 大小: 25.8 KB
  • 查看图片附件
发表评论
用户名: 匿名