个人学习Spring In Action学习笔记系列 (三) AOP
源码地址 https://github.com/spring-projects/spring-framework
U4 通知Bean
4.1 AOP简介
切面有助于实现交叉事务的模块化,每个模块是为特定领域提供服务,比如日志和安全就是一个交叉事务。
在面向切面编程AOP的思想里面,核心业务功能和切面功能分别独立进行开发,然后把切面功能和核心业务功能 "编织" 在一起,这就叫AOP
优点
- 模块可重用
- 减少了重复代码
- 让类着重于其主要功能
4.1.1 定义AOP术语
- 切入点(Pointcut) 在哪些类,哪些方法上切入(where)
- 通知(Advice) 在方法执行的什么实际(**when:**方法前/方法后/方法前后)做什么(**what:**增强的功能)
- 切面(Aspect) 切面 = 切入点 + 通知,通俗点就是:在什么时机,什么地方,做什么增强!
- 织入(Weaving) 把切面加入到对象,并创建出代理对象的过程。(由 Spring 来完成)
织入 在目标对象的多个生命周期都可以发生织入过程
- 编译时 切面在目标类编译时被织入。需要特殊的编译期,AspectJ
- 类加载时 切面在目标类加载到JVM时被织入。需要特殊的ClassLoader
- 运行时 切面在程序运行的某个时刻被织入,AOP会动态创建一个代理对象来委托给目标对象。这就是Spring AOP的织入切面方式
Spring利用代理类包裹切面,从而把他们织入到Spring管理的Bean里,代理类装作目标Bean,截取被通知的方法调用,再把这些调用转发到真正的目标Bean
Spring只支持方法连接点
Spring生成代理类的两种方式
- 如果目标对象是一个接口,使用JDK java.lang.reflect.Proxy类,允许Spring动态生成一个新类来实现必要的接口,织入任何通知,并且这些接口的任何调用都转发到目标类
- 如果不是一个接口,Spring就使用CGLIB库生成目标类的一个子类
4.2 创建典型的Spring切面
4.2.1 创建通知
4.2.2 定义切点和通知者
连接点就是程序代码中切面通知可以被织入的地点,切点是以某种方式选择全部连接点的一个子集来定义通知应该被织入的地点
Spring AOP中通知者把通知和切点关联起来,从而完整地定义了一个切面
4.2.3 使用ProxyFactoryBean
作为被通知者通知的Bean,它必须是被代理的。Spring的ProxyFactoryBean是个工厂Bean,用于生产一个代理
4.3 自动代理
ProxyFactoryBean会让Spring配置文件变得冗长,需要为每个被通知的Bean声明两个Bean:目标Bean 和 代理Bean
自动代理的两种方式
- Spring上下文里面声明通知者Bean
- 基于@AspectJ 注解切面的自动代理
自动代理@AspectJ切面