【JAVA笔记——道】java动态代理源码深入
2015-01-04 20:25
337 查看
JAVA动态代理是JAVA7的重要特性,其主要功能是通过proxy对象实现动态接口实现。
新建PracticeObject与PracticeObjectImpl,此处只是举例Impl没有具体实现
具体实现方式上
接下来我们使用Debug进行源码深入剖析,Into Proxy.newProxyInstance之后抛开错误检验相关进入第一个重要的方法
此处的loaderToCache是一个WeakHashMap(线程安全),在这将类装载器装入并对应生成一个空HashMap
Spring通过CgLib实现 动态代理(另外一种实现动态代理方式)
CgLib是一个开源动态代理框架,基于ASM实现动态代理。相较JDK Proxy技术,编译速度相对慢(Spring 启动慢的原因之一),执行速度较快。可以通过缓存加速编译~
public class PracticeInvocationHandler implements InvocationHandler{
private Object receiverObject; public PracticeinvocationHandler(Object object) { this.receiverObject = object; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("调用方法" + method.getName()); System.out.println("参数列表" + Arrays.deepToString(args)); return method.invoke(receiverObject, args); } }
新建PracticeObject与PracticeObjectImpl,此处只是举例Impl没有具体实现
public interface PracticeObject extends Comparable{ } public class PracticeObjectImpl implements PracticeObject { public int compareTo(Object o) { return 0; } }
具体实现方式上
public class PracticeProxy { public static void main(String[] args) { String str = "Hello World"; PracticeInvocationHandler handler = new PracticeInvocationHandler(str); ClassLoader loader = PracticeObject.class.getClassLoader(); PracticeObject obj = (PracticeObject) Proxy.newProxyInstance(loader, new Class[]{PracticeObject.class}, handler); obj.compareTo("Good"); } }
接下来我们使用Debug进行源码深入剖析,Into Proxy.newProxyInstance之后抛开错误检验相关进入第一个重要的方法
/* * Look up or generate the designated proxy class. */ Class cl = getProxyClass(loader, interfaces);
<span style="font-family: Arial, Helvetica, sans-serif; white-space: normal; background-color: rgb(255, 255, 255); "> </span>
<span style="font-family: Arial, Helvetica, sans-serif; white-space: normal; background-color: rgb(255, 255, 255); ">深入此方法,一个for循环中进行错误率的检测之后,我们可以看到</span>
<span style="font-family: Arial, Helvetica, sans-serif; white-space: normal; background-color: rgb(255, 255, 255); ">/* <span style="white-space:pre"> </span> * Using string representations of the proxy interfaces as <span style="white-space:pre"> </span> * keys in the proxy class cache (instead of their Class <span style="white-space:pre"> </span> * objects) is sufficient because we require the proxy <span style="white-space:pre"> </span> * interfaces to be resolvable by name through the supplied <span style="white-space:pre"> </span> * class loader, and it has the advantage that using a string <span style="white-space:pre"> </span> * representation of a class makes for an implicit weak <span style="white-space:pre"> </span> * reference to the class. */ </span>
<span style="font-family:Arial, Helvetica, sans-serif;"><span style="white-space: normal; "><span style="color:#cc6600;font-weight: bold; ">用字符串表示代理接口 作为 代理缓存的 标识(而不是类的对象) 就已经足够,因为我们仅仅需要代理接口可以被类加载器识别。这种方式有一个有点,这只是一个弱引用</span></span></span><pre name="code" class="java">/* * Find or create the proxy class cache for the class loader. */ Map cache; synchronized (loaderToCache) { cache = (Map) loaderToCache.get(loader); if (cache == null) { cache = new HashMap(); loaderToCache.put(loader, cache); } /* * This mapping will remain valid for the duration of this * method, without further synchronization, because the mapping * will only be removed if the class loader becomes unreachable. */ }
此处的loaderToCache是一个WeakHashMap(线程安全),在这将类装载器装入并对应生成一个空HashMap
Spring通过CgLib实现 动态代理(另外一种实现动态代理方式)
CgLib是一个开源动态代理框架,基于ASM实现动态代理。相较JDK Proxy技术,编译速度相对慢(Spring 启动慢的原因之一),执行速度较快。可以通过缓存加速编译~
相关文章推荐
- 深入源码理解-java动态代理
- hadoop源码研读之路(五)----Java动态代理
- java动态代理学习笔记
- 深入研究java中的静态代理和动态代理
- java动态代理学习笔记
- 深入解析java中的静态代理与动态代理
- java动态代理学习笔记
- 深入理解JAVA JDK动态代理机制
- 黑马程序员_Java高新技术_动态代理技术的深入理解
- Java动态代理学习笔记
- [Spring学习笔记 4 ] AOP 概念原理以及java动态代理
- java动态代理学习笔记
- 黑马程序员 java高新技术<四>--类加载器、动态代理技术的深入讲解与应用
- java静态和动态代理学习笔记
- java动态代理学习笔记
- java动态代理学习笔记
- java 动态代理深度学习(Proxy,InvocationHandler),含$Proxy0源码(转)
- java学习笔记14--动态代理
- Java动态代理学习笔记<转>
- Java 动态代理学习笔记