AOP
动态AOP自定义标签
如果声明了自定义的注解,那么就一定会在程序中的某个地方注册了对应的解析器。
注册或升级AnnotationAwareAspectJAutoProxyCreator
所有解析器,都是对BeanDefinitionParser接口的统一实现,入口都是从parse函数开始的
proxy-target-class=true 使用CGLIB代理;expose-proxy(有时候目标对象内部的自我调用将无法实现切面中的增强)=true 进行事务增强
public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
ParserContext parserContext, Element sourceElement) {
//1、注册或升级AopProxyCreator
BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
//2、对proxy-target-class以及expose-proxy属性的处理
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
//3、注册并通知,便于监听器做进一步处理
registerComponentIfNecessary(beanDefinition, parserContext);
}
创建AOP代理
AnnotationAwareAspectJAutoProxyCreator实现了BeanPostProcessor接口,而在实现BeanPostProcessor后,当Spring加载Bean时会在实例化之前调用其postProcesserAfter,查看AbstractAutoProxyCreator父类的postProcessAfterInitialization()方法,AOP逻辑的分析由此开始
- 真正创建代理主要包括两个步骤
- 获取增强方法或增强器
- 根据获取的增强进行代理
获取增强器
使用注解, findCandidateAdvisors的实现是由AnnotationAwareAspectJAutoProxyCreator类完成的;
buildAspectJAdvisors方法执行逻辑:
- 普通增强器的获取
- 增加同步实例化增强器
- 如果寻找的增强器 不为空而且又配置了增强延迟初始化,那么就需要在首位加入同步实例化增强器。同步实例化增强器 SyntheticInstantiationAdvisor
- 获取DeclareParents注解
寻找匹配的增强器
创建代理
- createProxy对ProxyFactory做一些初始化操作,为真正创建代理做准备;
创建AOP静态代理
是指在虚拟机启动时通过改变目标对象字节码分方式来完成对目标对象的增强。
Instrumentation使用
- jdk1.5引入了java.lang.instrument,自定义实现一个Java agent,通过agent来修改一个类的字节码即改变一个类;
- 自定义ClassFileTransformerl类
- 详细(转载)
自定义标签
registerBeanDefinitionParser(“load-time-weaver”, new LoadTimeWeaverBeanDefinitionParser());
织入
参考书籍《Spring源码深度解析》