【代理】【三】代理源码解析-Cglib代理-环境准备以及简单介绍
1 前言
之前我们看过了JDK动态代理的源码了,今天我们大概花三四篇(因为一篇文章东西太多写的人费劲看的人也累哈)来看看Cglib的代理源码过程,其中涉及到asm包中的东西构建类代码什么的这里我暂时不做深入了解哈。
2 环境准备
- 源码下载地址:http://www.java2s.com/Code/Jar/c/cglib.htm;
- 源码本身没有 asm 相关的依赖我们需要在 pom.xml 中添加一下依赖:
<dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.7</version> </dependency> <dependency> <groupId>asm</groupId> <artifactId>asm</artifactId> <version>3.3.1</version> </dependency> <dependency> <groupId>org.apache.ant</groupId> <artifactId>ant</artifactId> <version>1.10.9</version> </dependency> <dependency> <groupId>asm</groupId> <artifactId>asm-util</artifactId> <version>3.3.1</version> </dependency>
- 好我们测试一个例子,看看运行是否正常,没啥问题我们就能愉快的看源码并且调试了。
public class MyMethodInterceptor implements MethodInterceptor { @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("我是执行前"); Object result = methodProxy.invokeSuper(o, objects); System.out.println("我是执行后"); return result; } } public class UserServiceImpl { private String name; public void say() { System.out.println("111"); } } public static void main(String[] args) { // 设置代理文件输出位置 System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "./code"); // 创建 cglib 代理类的核心对象 Enhancer enhancer = new Enhancer(); // 设置要创建代理的类 enhancer.setSuperclass(UserServiceImpl.class); // 跟 JDK 代理一样,增强的逻辑 enhancer.setCallback(new MyMethodInterceptor()); // 创建代理,并调用 UserServiceImpl userService = (UserServiceImpl) enhancer.create(); userService.say(); }
3 核心类简介
整理完环境,我们大概看一下创建代理对象一些核心类,先了解一下,方便看源码:
-
MethodInterceptor 这个就类比jdk的InvocationHandler做增强逻辑的;
-
创建代理类涉及到的核心类从上到下:ClassGenerator、AbstractClassGenerator(Enhancer、Generator)里边用的模板模式
ClassGenerator 顶层接口
AbstractClassGenerator 抽象实现类 模板的枢纽
Enhancer 这个就是创建 cglib代理对象的核心,也是入口
Generator 这个是用来辅助 Enhancer 的,用于创建代理的key,也是缓存的key,下篇会先讲它
从类图上我们再直观的感受下:
这里我简单画了一下上边示例整体的代理创建过程,先感受下大致的过程。标号的1、2、3、4分别表示对应的类的内部发生了什么样的变化。其中一点没画,就是 Enhancer的 create()方法里需要的 key,这个就需要我们的 KeyFactory 来创建,而 KeyFactory 又是借助 Generator 通过创建 EnhancerKey 的代理对象来创建的,下节我们会先讲这个哈。
4 小结
好了环境调试完毕,大概的核心类我们都了解是什么了,我们下节会先从 Key 的创建开始讲起,有理解不对的地方欢迎指正哈。