引言

源码分析入口为:AbstractAdvisorAutoProxyCreator的getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource)方法:

1
2
3
4
5
6
7
8
9
10
11
12
@Override
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
//找到所有适合自动代理该类的Advisor。
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
// null
return DO_NOT_PROXY;
}
return advisors.toArray();
}

findEligibleAdvisors流程入口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//找到所有适合自动代理该类的Advisor。
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
//找到所有要在自动代理中使用的候选Advisor。
List<Advisor> candidateAdvisors = findCandidateAdvisors();
//搜索给定的候选Advisor,以找到可以应用于指定bean的所有Advisor。
//通过 ClassFilter 和 MethodMatcher 对目标类和方法进行匹配
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
// 拓展操作
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
// 根据顺序对Advisor进行排序。
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}

这里面有两个重要的方法:

  1. findCandidateAdvisors()
    获取所有的Advisor。
  2. findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName)
    获取当前bean所匹配的Advisor。

1、findCandidateAdvisors

这个方法由子类AnnotationAwareAspectJAutoProxyCreator实现:

1
2
3
4
5
6
7
8
9
10
11
12
@Override
protected List<Advisor> findCandidateAdvisors() {
// 调用父类AbstractAdviceAutoProxyCreator的方法,获取配置文件中的Advisor
// 最后会调用到BeanFactoryAdvisorRetrievalHelper的findAdvisorBeans()方法
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
if (this.aspectJAdvisorsBuilder != null) {
//解析 @Aspect 注解,并构建通知器
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}

首先会调用父类AbstractAdvisorAutoProxyCreator中的findCandidateAdvisors方法,
从当前IOC容器中获取所有Advisor:

1
2
3
4
5
6
7
8
9
10
/**
* 找到所有要在自动代理中使用的候选Advisors。
*
* @return 候选Advisors
*/
protected List<Advisor> findCandidateAdvisors() {
Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
return this.advisorRetrievalHelper.findAdvisorBeans();
}

BeanFactoryAdvisorRetrievalHelper中的findAdvisorBeans:

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
	
/**
* 找到当前bean工厂中所有合格的Advisor bean,
* 忽略FactoryBeans并排除当前正在创建的bean。
* @return {@link Advisor} bean的列表
* @see #isEligibleBean
*/
public List<Advisor> findAdvisorBeans() {
// 确定advisor bean名称列表(如果尚未缓存)。
String[] advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
// 不要在这里初始化FactoryBeans:我们需要不初始化所有常规bean,让自动代理创建器应用于它们!
// 从容器中获取所有Advisor类型的bean的名称,并设置缓存
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
// 如果工厂中没有advisor,直接返回空的数组
if (advisorNames.length == 0) {
return new ArrayList<>();
}

List<Advisor> advisors = new ArrayList<>();
//迭代所有advisorNames
for (String name : advisorNames) {
//默认true,确认切面bean是否合适
if (isEligibleBean(name)) {
//跳过当前正在创建中的advisor
if (this.beanFactory.isCurrentlyInCreation(name)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping currently created advisor '" + name + "'");
}
}
else {
try {
//获取Advisor实例
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)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping advisor '" + name +
"' with dependency on currently created bean: " + ex.getMessage());
}
// 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;
}

之后获取所有被@Aspect注解修饰的切面:
aspectJAdvisorsBuilder.buildAspectJAdvisors()
BeanFactoryAspectJAdvisorsBuilder:

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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/**
* 在当前bean工厂寻找AspectJ注解的切面bean,
* 返回到表示它们的Spring AOP Advisors列表。
* 为每个AspectJ advice方法创建一个Spring Advisor。
*
* @return Advisor beans 列表
* @see #isEligibleBean
*/
public List<Advisor> buildAspectJAdvisors() {
//切面bean的名称列表
List<String> aspectNames = this.aspectBeanNames;
//如果缓存中为空
if (aspectNames == null) {
//锁住当前对象
synchronized (this) {
//切面bean的名称列表
aspectNames = this.aspectBeanNames;
//双重检查
if (aspectNames == null) {
List<Advisor> advisors = new ArrayList<>();
aspectNames = new ArrayList<>();
//获取所有的Object类型的bean名称
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
//迭代,这里beanNames不可能为空
for (String beanName : beanNames) {
//是否合适
if (!isEligibleBean(beanName)) {
continue;
}
//我们必须注意不要急于实例化bean,
// 因为在本例中,它们将被Spring容器缓存,但不会被weaved。
//获取Class类型
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
//必须有Aspect注解修饰且方法名不能以 AJC_MAGIC = "ajc$"开头
//后一种的原因是,用代码风格(AspectJ语言)编写的切面在ajc编译时也有注释,
//并且带有-1.5标志,不能被Spring AOP使用。
if (this.advisorFactory.isAspect(beanType)) {
//搜集切面beanName
aspectNames.add(beanName);
//切面元数据组装
AspectMetadata amd = new AspectMetadata(beanType, beanName);
//切面实例化模型为SINGLETON
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
//获取Advisors
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);
}
// PERTHIS,
// PERTARGET,
// PERCFLOW,
// PERCFLOWBELOW,
// PERTYPEWITHIN;
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();
}
List<Advisor> advisors = new ArrayList<>();
//迭代缓存中的切面beanName
for (String aspectName : aspectNames) {
//单例切面
List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
advisors.addAll(cachedAdvisors);
} else {
//获取缓存中的切面工厂
MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
//获取Advisor
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
return advisors;
}

这里有个重要的方法:

1
2
//获取Advisors
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);

比较复杂,所以打算后面分析,本篇把流程走完。

2、findAdvisorsThatCanApply

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* 搜索给定的候选Advisors,以找到可以应用于指定bean的所有Advisors。
*
* @param candidateAdvisors 候选Advisors
* @param beanClass beanClass
* @param beanName beanName
* @return 可以应用于指定bean的所有Advisors
* @see ProxyCreationContext#getCurrentProxiedBeanName()
*/
protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

//ThreadLocal在Advisor匹配期间保存当前代理bean名称。
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
//确定适用于给定类的candidateAdvisors列表的子列表。
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
} finally {
//ThreadLocal清除bean名称
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}

这里面的AopUtils的方法通过ClassFilter的 matches(Class clazz)方法,和MethodMatcher的matches(Method method, Class targetClass)方法过滤出当前bean实例使用的Advisors。
这个方法也很重要,难度也比较大,所以也拉出来单独分析。

经过上面的分析,还剩下两块主要的部分没有分析:

  1. 通过注解@AspectJ获取Advisiors
    通过AspectJAdvisorFactory与ListableBeanFactory获取Advisor列表,为啥是列表?因为一个切面中会有多个Advice,
    而Advisor与Advice是一对一的关系,所以一个切面会有多个Advisor:
    1
    2
    //获取Advisors
    List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
  2. ClassFilter与MethodMatcher过滤出当前bean实例的使用Advisors

篇幅太长,下面分两篇文章分析。

tencent.jpg