慕课网《 探秘Spring AOP》笔记
织入时机
- 编译期(AspectJ)
- 类加载时(AspectJ 5+)
- 运行时(Spring AOP)
运行时织入
- 运行时织入如何实现
代理对象 - 代理的类型
静态代理
动态代理 - 动态代理实现
基于接口代理
基于继承代理
代理AOP对象

- 调用方(Caller)
- 目标对象(Target)
- 代理对象(Proxy)
调用方通过代理对象间接地访问目标对象,反过来说,目标对象委托代理对象与客户度交互。因此,代理对象可以在目标对象方法的前后执行额外的操作。

- 客户端通过接口来调用目标对象(面向接口编程)。由于目标对象具备的方法代理对象也同样需要具备,所以目标对象与代理对象同为该接口的实现。
- 代理对象将真正的方法委托给目标对象执行,自己执行AOP织入的额外的逻辑。
代码示例(静态代理)
-
项目结构
项目结构
-
定义接口
定义接口
-
定义目标类
目标类实现了接口
目标类
-
定义代理类
代理类也实现了目标类实现的接口
代理类
-
客户端
客户端
-
执行结果
执行结果
静态代理
静态代理的缺点
- 要代理的方法越多,重复的逻辑越多。
动态代理
动态代理的两类实现
- 基于接口代理(JDK代理)
- 基于继承代理(Cglib代理)
JDK代理实现要点
- 类:使用
java.lang.reflect.Proxy
生成代理类。 - 接口:代理类需要实现InvocationHandler接口
- 只能基于接口实现动态代理
代码示例
-
项目结构
项目结构
- JDK代理类
该类实现了java.lang.reflect.InvocationHandler
接口,并通过反射动态获取目标类方法。
JDK代理类
-
客户端
客户端
Cglib实现
代码示例
-
项目结构
项目结构
-
MethodInterceptor实现类
MethodInterceptor实现类
-
客户端
客户端
JDK与Cglib代理对比
- JDK只能针对有接口的类的接口方法进行动态代理,无法对private类进行代理。
- Cglib基于继承来实现代理,无法对static、final、private类进行代理。
Spring如何创建代理Bean


- 如果目标对象实现了接口,则默认采用JDK动态代理。
- 如果目标对象没有实现接口,则采用Cglib进行动态代理。
- 如果目标对象实现了接口,且强制Cglib代理,则使用Cglib代理。
强制使用Cglib代理的方法

网友评论