3 | Spring:AOP实现原理
看给容器中注册了什么组件,这个组件什么时候工作,功能是什么?
@EnableAspectJAutoProxy
工作流程
①首先从@EnableAspectJAutoProxy
注解入手,它使用@Import注解,加入了一个实现了ImportBeanDefinitionRegistrar
的类,叫做AspectJAutoProxyRegistrar
1 |
|
②也就是说它会往IOC容器中加入相应的bean,到底加入了什么呢?
1 |
|
从registerBeanDefinitions()
方法开始,可以一直跟到AopConfigUtils.registerOrEscalateApcAsRequired()
,在这个函数里面,它往IOC容器中注册了一个AnnotationAwareAspectJAutoProxyCreator
,名称为AUTO_PROXY_CREATOR_BEAN_NAME,即org.springframework.aop.config.internalAutoProxyCreator
。
1 |
|
AnnotationAwareAspectJAutoProxyCreator
了解AnnotationAwareAspectJAutoProxyCreator
的功能,就等于知道了AOP的原理。首先看看它的继承关系图。
它的父类中,实现了两个接口,这两个接口参见bean的生命周期,所以搞清楚这两个接口在何时工作、工作内容即可搞明白AOP的整理流程。
①有一个BeanFactoryAware
接口;
②还有一个SmartInstantiationAwareBeanPostProcessor
接口,它继承自InstantiationAwareBeanPostProcessor
,它继承自BeanPostProcessor
,但是与BeanPostProcessor
不一样。InstantiationAwareBeanPostProcessor
作用于实例化阶段的前后,BeanPostProcessor
作用于初始化阶段的前后。
工作时机
BeanFactoryAware
按照上面类图中,从最先实现BeanFactoryAware接口的类,依次往下找相关的实现,即setBeanFactory()方法:
AbstractAutoProxyCreator.setBeanFactory()
1
2
3
4
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}AbstractAdvisorAutoProxyCreator.setBeanFactory()
1
2
3
4
5
6
7
8
9
10
11
public void setBeanFactory(BeanFactory beanFactory) {
super.setBeanFactory(beanFactory);
...
initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
}
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
this.advisorRetrievalHelper =
new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
}AnnotationAwareAspectJAutoProxyCreator
1
2
3
4
5
6
7
8
9
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.initBeanFactory(beanFactory);
if (this.aspectJAdvisorFactory == null) {
this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
}
this.aspectJAdvisorsBuilder =
new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
}分别打上断点。
SmartInstantiationAwareBeanPostProcessor
按照上面的类图,从最先实现SmartInstantiationAwareBeanPostProcessor
接口的类开始,逐步往下寻找相关方法实现,如下:
AbstractAutoProxyCreator
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public Object postProcessAfterInitialization( { Object bean, String beanName)
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
Object cacheKey = getCacheKey(beanClass, beanName);
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
// Create proxy here if we have a custom TargetSource.
// Suppresses unnecessary default instantiation of the target bean:
// The TargetSource will handle target instances in a custom fashion.
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
return null;
}分别打上断点。
工作流程梳理
InstantiationAwareBeanPostProcessor
作为一个bean,被加载到beanFactory
中。并执行其BeanFactoryAware
接口的方法。- 当其他bean初始化时,
InstantiationAwareBeanPostProcessor
会拦截其他bean的实例化,并创建代理对象返回。也就是执行postProcessBeforeInstantiation
和postProcessAfterInitialization
。
上面的结论是错的,经过后续的debug跟代码,发现最终Divider被Cglib代理是在BeanPostProcessor的afterInitialization中,如下:
其中的创建代理对象的逻辑如下:
Cglib执行代理流程
这个像一个有限套娃,也有点像递归,这种包装办法真的很厉害,很服气。
1 |
|
Netty源码学习系列④接收消息
Spring Cloud Alibaba Sentinel简易搭建与配置
Spring Boot Admin构建及用途
xxljob分布式定时任务
ELK日志系统搭建 elasticsearch、logstash、kibana
kafka集群搭建
redis集群搭建
Spring Boot自动配置原理
3 | Spring:AOP实现原理