盘点 AOP AOP 的初始化

这是我参与更文挑战的第17天,活动详情查看: 更文挑战

首先分享之前的所有文章 , 欢迎点赞收藏转发三连下次一定 >>>> 😜😜😜

文章合集 : 🎁 juejin.cn/post/694164…

Github : 👉 github.com/black-ant

当前案例源码 : 👉 Github AOP Source

一 . 前言

之前盘点了 IOC 的相关流程 , 这一篇终于来说一说 AOP 了 , 整个系列会从 :

  • AOP 的初始化
  • AOP 代理类的创建
  • AOP 的拦截
  • AOP 的代理方法调用

以上几个章节分别进行阐述

二 . AOP 的调用入口

Aop 的初始化是指在哪个环节开始 Aop 的配置 :

结合之前 IOC 了解到的 , Aop 的核心还是通过 postProcess 来完成 , 分为 Before 和 After 2个流程

  • applyBeanPostProcessorsBeforeInstantiation (createBean 创建)
  • applyBeanPostProcessorsAfterInitialization (initializeBean 是处理)

// 路线一 : 处理 Aware , 可以通过 getCustomTargetSource 提前生成代理

  • C- AbstractAutowireCapableBeanFactory # createBean
  • C- AbstractAutowireCapableBeanFactory # resolveBeforeInstantiation
  • C- AbstractAutowireCapableBeanFactory # applyBeanPostProcessorsBeforeInstantiation
  • C- AnnotationAwareAspectJAutoProxyCreator # postProcessBeforeInstantiation

// 路线二 : 处理 BeanPostProcessor , 正常代理创建逻辑

  • C- AbstractAutowireCapableBeanFactory # createBean
  • C- AbstractAutowireCapableBeanFactory # doCreateBean
  • C- AbstractAutowireCapableBeanFactory # initializeBean
  • C- AbstractAutowireCapableBeanFactory # applyBeanPostProcessorsAfterInitialization
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
java复制代码// Step 1 : 在 createBean 中对 applyBeanPostProcessorsBeforeInstantiation 进行处理
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {

// .... 省略部分逻辑 , 此处初始化代理类
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);

// 此内将会调用 Step 2 创建逻辑 , 同时处理代理类
Object beanInstance = doCreateBean(beanName, mbdToUse, args);

//........
return beanInstance;

}


// Step 2 : 在 IOC 流程 initializeBean 中 , 会对 PostProcessors 进行处理
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {

//..........
invokeInitMethods(beanName, wrappedBean, mbd);

// 调用 applyBeanPostProcessorsAfterInitialization 处理 AfterPostProcessors
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

return wrappedBean;
}

处理后 , 在调用bean本身之前将委托给指定的拦截器 , 拦截器分为2种 :

  • common : 为它创建的所有代理共享
  • specific : 每个bean实例唯一

代理的限制 :
子类可以应用任何策略来决定一个bean是否要被代理,例如根据类型、名称、定义细节等

为什么有 getCustomTargetSource 提前生成 ?

getCustomTargetSource 是通过 TargetSourceCreator 对象 ,在 Bean 实例化之前 , 为其生成代理对象 .

该模式需要自行定制 , 详见 附录 : 创建 customTargetSource

2.1 applyBeanPostProcessorsBeforeInstantiation

Step 1 : 调用 PostProcessorsBefore C- AbstractAutowireCapableBeanFactory

此处主要会调用 org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator 进行处理

1
2
3
4
5
6
7
8
java复制代码for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
// idp -> org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
//..........
}
}

Step 2 : 配置前置条件 C- 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
java复制代码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;
}
// isInfrastructureClass -> 不应该被代理的基础结构类
// shouldSkip -> 注意 , 子类重写 shouldSkip , 用于跳过自动代理
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
// PRO21001 -> advisedBeans 的作用
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}

// 如果有一个自定义的TargetSource,那么在这里创建代理
// TargetSource将以自定义的方式处理目标实例
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
// 自行定制 CustomTargetSource 逻辑后 , 即会在此处创建代理
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;
}

Step 2-1 : 返回目标实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
java复制代码
C- getCustomTargetSource : 为bean实例创建目标源。如果设置,使用任何TargetSourceCreators
protected TargetSource getCustomTargetSource(Class<?> beanClass, String beanName) {
// 此处要求存在创建者, 需要在执行定制
if (this.customTargetSourceCreators != null &&
this.beanFactory != null && this.beanFactory.containsBean(beanName)) {
for (TargetSourceCreator tsc : this.customTargetSourceCreators) {
// 通过创建者回去目标对象代理类
TargetSource ts = tsc.getTargetSource(beanClass, beanName);
if (ts != null) {
return ts;
}
}
}

// 未定义 customTargetSource 会在此处直接返回
return null;
}

2.2 applyBeanPostProcessorsAfterInitialization

前面说的是在 Bean 实例化之前创建代理 ,但是通常情况下 , 是在 Bean 实例化之后进行代理逻辑的创建

Step 1 : IOC initializeBean 入口

IOC initializeBean 时 , 调用 applyBeanPostProcessorsAfterInitialization 逻辑

1
2
3
java复制代码if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

Step 2 : applyBeanPostProcessorsAfterInitialization 中循环 BeanPostProcessor 进行处理

1
2
3
4
5
java复制代码for (BeanPostProcessor processor : getBeanPostProcessors()) {
// BeanPostProcessor -> org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator
Object current = processor.postProcessAfterInitialization(result, beanName);
//........
}

PS : 可以看到 , 这里拿到的Bean 的 PostProcessor 就是 AnnotationAwareAspectJAutoProxyCreator

Step 3 : AbstractAutoProxyCreator # postProcessAfterInitialization 构建代理对象

如果bean被标识为代理,则使用配置的拦截器创建代理

1
2
3
4
5
6
7
8
9
10
java复制代码public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
// cacheKey 用来标识
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}

Step 4 : wrapIfNecessary 正式创建代理类 C- 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
java复制代码
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}

// 如果配置了通知 ,则创建Proxy 代理
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 核心逻辑 , 创建代理 -> 2.2 Aop 代理类的创建
// 可以看到 , 这里构建了一个 SingletonTargetSource -> PRO21002 : TargetSource 是什么 ?
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}

this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}

PRO21001 -> advisedBeans 的作用

1
2
3
4
5
6
java复制代码// advisedBeans 用于标识当前 Bean 的代理状态 , 该对象 key 为 getCacheKey 获取
Map<Object, Boolean> advisedBeans = new ConcurrentHashMap<>(256);

- 如果无需代理 -> advisedBeans.put(cacheKey, Boolean.FALSE)
- 如果已经代理 -> advisedBeans.put(cacheKey, Boolean.TRUE)
- 最终无操作(没用注解标注) -> advisedBeans.put(cacheKey, Boolean.FALSE)

PRO21002 : TargetSource 是什么 ?

可以看到 , 这里实际上和下面的 applyBeanPostProcessorsAfterInitialization 类似 , 那么上面是处理什么?

TargetSource用于获取AOP调用的当前”目标” , 在Spring代理目标bean的时候,其并不是直接创建一个目标bean的对象实例的,而是通过一个TargetSource类型的对象将目标bean进行封装 , 然后通过 getTarget 获取目标对象

TargetSource 是一个接口 , 可以通过下图看到其本身的体系结构 :

TargetSource-system.png

三 . 补充点 : Advisors 详解之 getAdvicesAndAdvisorsForBean 流程

此部分对 getAdvicesAndAdvisorsForBean 的流程进行详细的浏览

Step 1 : 筛选 Advices C- AbstractAutoProxyCreator

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
java复制代码M- getAdvicesAndAdvisorsForBean
Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName,TargetSource customTargetSource)
?- 返回给定的bean是否要被代理,要应用哪些附加通知(例如AOP Alliance拦截器)和建议器

// 该类主要有2个实现类 : AbstractAdvisorAutoProxyCreator , BeanNameAutoProxyCreator

protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {

List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}

Step 2 : 为自动代理这个类找到所有符合条件的advisor

1
2
3
4
5
6
7
8
9
10
11
12
java复制代码protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// Step 2-1 : 查询切面对应的所有的通知
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// Step 2-2 : 筛选与类对应的织入切点
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
// 空对象, 待实现
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}

Step 2-1 : BeanFactoryAdvisorRetrievalHelper 获取通知对象

2-1-1 : 先调用具体实现类 (AnnotationAwareAspectJAutoProxyCreator)

👉该过程中对切面进行了扫描 ,并且缓存了所有的通知点

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
java复制代码protected List<Advisor> findCandidateAdvisors() {
// 根据超类规则添加所有找到的Spring 通知
List<Advisor> advisors = super.findCandidateAdvisors();
// 为bean工厂中的所有AspectJ方面构建 通知
if (this.aspectJAdvisorsBuilder != null) {
// 2-1-1-1
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}

// 2-1-1-1 : 构建通知者
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;

if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new ArrayList<>();
aspectNames = new ArrayList<>();
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
}
// 需要在实例化缓存之前被处理
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
// 过滤出切面 Bean , debug 过程中会拿到我自己定义的切面
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);
// 获取切面元数据 -> PIC0001
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
// AspectInstanceFactory的子接口,它返回与aspectj注释类关联的AspectMetadata
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
// 获得所有得通知点 -> PIC0002
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
// 此处成功放入缓存中
this.advisorsCache.put(beanName, classAdvisors);
}
else {
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
} else {
// Per target or per this.
if (this.beanFactory.isSingleton(beanName)) {
throw new IllegalArgumentException("Bean with name '" + beanName +
"' is a singleton, but aspect instantiation model is not singleton");
}
MetadataAwareAspectInstanceFactory factory =
new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
this.aspectFactoryCache.put(beanName, factory);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
this.aspectBeanNames = aspectNames;
return advisors;
}
}
}

if (aspectNames.isEmpty()) {
return Collections.emptyList();
}

// 循环 aspect 切面 , 添加通知
List<Advisor> advisors = new ArrayList<>();
for (String aspectName : aspectNames) {
List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
advisors.addAll(cachedAdvisors);
} else {
MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
return advisors;
}

PIC0001 : 切面元数据

image.png

PIC0002 : 待通知的切点
image.png

2-1-2 : 调用父类

1
2
3
java复制代码protected List<Advisor> findCandidateAdvisors() {
return this.advisorRetrievalHelper.findAdvisorBeans();
}

2-1-3 : 实际方法

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
java复制代码public List<Advisor> findAdvisorBeans() {
// 确定advisor bean名称列表
String[] advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the auto-proxy creator apply to them!
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
if (advisorNames.length == 0) {
return new ArrayList<>();
}

List<Advisor> advisors = new ArrayList<>();
for (String name : advisorNames) {
if (isEligibleBean(name)) {
if (this.beanFactory.isCurrentlyInCreation(name)) {
// log 省略
} else {
try {
advisors.add(this.beanFactory.getBean(name, Advisor.class));
} catch (BeanCreationException ex) {
Throwable rootCause = ex.getMostSpecificCause();
if (rootCause instanceof BeanCurrentlyInCreationException) {
BeanCreationException bce = (BeanCreationException) rootCause;
String bceBeanName = bce.getBeanName();
if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
// Ignore: indicates a reference back to the bean we're trying to advise.
// We want to find advisors other than the currently created bean itself.
continue;
}
}
throw ex;
}
}
}
}
return advisors;
}

Step 2-2 : 搜索给定的候选advisor以找到适用于指定bean的所有advisor

1
2
3
4
5
6
7
8
9
10
11
java复制代码
protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
} finally {
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}

Step 2-3 : sort 排序

1
2
3
4
5
6
7
java复制代码protected List<Advisor> sortAdvisors(List<Advisor> advisors) {
AnnotationAwareOrderComparator.sort(advisors);
return advisors;
}

// [Pro] : AnnotationAwareOrderComparator 是什么 ?
AnnotationAwareOrderComparator是OrderComparator的扩展,它支持Spring的Ordered接口以及Order和Priority注释

总结

AOP 初始化阶段基本上就完成了 , 后续再来看一下代理类的创建 . 来总结一下这篇文档得所有概念 :

  • 由 initializeBean 开启 AOP 的主处理逻辑
  • AbstractAutowireCapableBeanFactory 调用 applyBeanPostProcessorsBeforeInstantiation 创建自定义代理类
  • AbstractAutowireCapableBeanFactory 调用 applyBeanPostProcessorsAfterInitialization 筛选通知器

附录 : 创建 customTargetSource

参考地址 (原文这一块写的更加详细) @ blog.csdn.net/qq_39002724…

Step 1 :准备 CustomTargetSource

1
2
3
4
5
6
7
8
9
10
java复制代码public class DefaultCustomTargetSource extends AbstractBeanFactoryBasedTargetSource {

private Logger logger = LoggerFactory.getLogger(this.getClass());

@Override
public Object getTarget() throws Exception {
logger.info("------> 进入 [DefaultCustomTargetSource] , 返回当前目标对象 <-------");
return getBeanFactory().getBean(getTargetBeanName());
}
}

Step 2 : 准备创建者

该对象用于返回创建的 CustomTargetSource

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
java复制代码public class DefaultCustomerTargetSourceCreator extends AbstractBeanFactoryBasedTargetSourceCreator {

private Logger logger = LoggerFactory.getLogger(this.getClass());

@Override
protected AbstractBeanFactoryBasedTargetSource createBeanFactoryBasedTargetSource(Class<?> beanClass, String beanName) {
logger.info("------> CustomerTargetSourceCreator build : [进入流程创建过程 , 返回默认资源类 DefaultCustomTargetSource] <-------");
if (getBeanFactory() instanceof ConfigurableListableBeanFactory) {
if (beanClass.isAssignableFrom(OtherService.class)) {
return new DefaultCustomTargetSource();
}
}
return null;
}
}

Step 3 : CustomTargetSource 资源配置

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
java复制代码@Component
public class CustomTargetSourceCreatorConfig implements BeanPostProcessor, PriorityOrdered, BeanFactoryAware {

private Logger logger = LoggerFactory.getLogger(this.getClass());

private BeanFactory beanFactory;

@Override
public int getOrder() {
return 45;
}

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
logger.info("------> 进入 CustomTargetSourceCreatorConfig 初始化加载逻辑 , 返回默认创建者 <-------");
if (bean instanceof AnnotationAwareAspectJAutoProxyCreator) {
AnnotationAwareAspectJAutoProxyCreator annotationAwareAspectJAutoProxyCreator = (AnnotationAwareAspectJAutoProxyCreator) bean;
DefaultCustomerTargetSourceCreator customTargetSourceCreator = new DefaultCustomerTargetSourceCreator();
customTargetSourceCreator.setBeanFactory(beanFactory);
annotationAwareAspectJAutoProxyCreator.setCustomTargetSourceCreators(customTargetSourceCreator);
}
return bean;
}

@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
}

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%