引言

AspectJAdvisorFactory:
从使用AspectJ注释语法注释的类中创建Spring AOP advisor。
首先搬出接口方法定义:

1
2
3
4
5
6
7
/**
* 为指定切面实例上的所有At-AspectJ注释方法构建Spring AOP advisor。
* @param aspectInstanceFactory 切面实例工厂
* (不是切面实例本身,以避免过早实例化)
* @return 该类的advisor列表
*/
List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory);

他的实现类ReflectiveAspectJAdvisorFactory:

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
@Override
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
//从切面元数据中获取切面类
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
//获取切面beanName
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
//校验:如果没有@Aspect注解或者是抽象的抛出异常,
// 不支持percflow和percflowbelow实例化模型
validate(aspectClass);

// 我们需要用装饰器包装MetadataAwareAspectInstanceFactory
// 所以它只实例化一次。
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);

List<Advisor> advisors = new ArrayList<>();

//getAdvisorMethods返回不是@Pointcut注解修饰的方法
for (Method method : getAdvisorMethods(aspectClass)) {

//获取当前方法的增强器Advisor
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
if (advisor != null) {
advisors.add(advisor);
}
}

// If it's a per target aspect, emit the dummy instantiating aspect.
// 如果寻找的增强器不为空而且又配置了增强延迟初始化那么需要在首位加入同步实例化增强器
if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);
}

// Find introduction fields.
// 获取 DeclareParents 注解
for (Field field : aspectClass.getDeclaredFields()) {
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}

return advisors;
}

对每个方法获取普通增强器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Override
@Nullable
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrderInAspect, String aspectName) {
//校验
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
//获取当前方法的切入点
AspectJExpressionPointcut expressionPointcut = getPointcut(candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
if (expressionPointcut == null) {
return null;
}
//根据切点信息生成增强器
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod, this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}

在这分为两个步骤:

  1. 获取AspectJ表达式切点
  2. 创建Advisor实现类
    下面分别分析:

1、获取AspectJ表达式切点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Nullable
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
//获取方法上使用的注解:@Pointcut;@Around; @Before; @After;@AfterReturning;@AfterThrowing;
AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}

//创建AspectJExpressionPointcut对象
AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
//设置切点表达式
ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
if (this.beanFactory != null) {
ajexp.setBeanFactory(this.beanFactory);
}
return ajexp;
}

2、创建Advisor实现类

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
public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {

//各种值的封装
this.declaredPointcut = declaredPointcut;
this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
this.methodName = aspectJAdviceMethod.getName();
this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
this.aspectJAdviceMethod = aspectJAdviceMethod;
this.aspectJAdvisorFactory = aspectJAdvisorFactory;
this.aspectInstanceFactory = aspectInstanceFactory;
this.declarationOrder = declarationOrder;
this.aspectName = aspectName;

//如果配置了增强延迟初始化
if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
// 切入点的静态部分是一个惰性类型。
Pointcut preInstantiationPointcut = Pointcuts.union(aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);

// 使之动态:必须从预实例化状态更改为后实例化状态。
// 如果它不是一个动态切入点,那么在第一次评估之后,Spring AOP基础设施可能会对它进行优化。
this.pointcut = new PerTargetInstantiationModelPointcut(this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
this.lazy = true;
} else {
// A singleton aspect.
this.pointcut = this.declaredPointcut;
this.lazy = false;
// 非懒加载时,直接初始化
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
}
}

里面包括了一个重要的方法instantiateAdvice,即创建Advice:

1
2
3
4
5
6
private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
//获取Advice
Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
return (advice != null ? advice : EMPTY_ADVICE);
}

在AspectJAdvisorFactory接口中方法getAdvice定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* 为给定的AspectJ通知方法构建Spring AOP通知。
* @param candidateAdviceMethod 候选通知方法
* @param expressionPointcut AspectJ表达式切入点
* @param aspectInstanceFactory 切面实例工厂
* @param declarationOrder 切面内的声明顺序
* @param aspectName 切面的名称
* @return 如果方法不是AspectJ通知方法,
* 或者它是一个切入点,其他通知将使用它,但它本身不会创建Spring通知,则为null
* @see org.springframework.aop.aspectj.AspectJAroundAdvice
* @see org.springframework.aop.aspectj.AspectJMethodBeforeAdvice
* @see org.springframework.aop.aspectj.AspectJAfterAdvice
* @see org.springframework.aop.aspectj.AspectJAfterReturningAdvice
* @see org.springframework.aop.aspectj.AspectJAfterThrowingAdvice
*/
@Nullable
Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName);

ReflectiveAspectJAdvisorFactory实现:

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
@Override
@Nullable
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {

//获取切面类
Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
//校验
validate(candidateAspectClass);
//获取方法上面注释的注解
AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}

// 如果我们到这里,我们知道我们有一个AspectJ方法。
// Check that it's an AspectJ-annotated class
if (!isAspect(candidateAspectClass)) {
throw new AopConfigException("Advice must be declared inside an aspect type: " +
"Offending method '" + candidateAdviceMethod + "' in class [" +
candidateAspectClass.getName() + "]");
}

if (logger.isDebugEnabled()) {
logger.debug("Found AspectJ method: " + candidateAdviceMethod);
}

AbstractAspectJAdvice springAdvice;

//注解类型
switch (aspectJAnnotation.getAnnotationType()) {
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
case AtAround:
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtBefore:
springAdvice = new AspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfter:
springAdvice = new AspectJAfterAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfterReturning:
springAdvice = new AspectJAfterReturningAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
case AtAfterThrowing:
springAdvice = new AspectJAfterThrowingAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
break;
default:
throw new UnsupportedOperationException(
"Unsupported advice type on method: " + candidateAdviceMethod);
}

// Now to configure the advice...
springAdvice.setAspectName(aspectName);
springAdvice.setDeclarationOrder(declarationOrder);
// 获取方法的参数列表名称
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
if (argNames != null) {
springAdvice.setArgumentNamesFromStringArray(argNames);
}
springAdvice.calculateArgumentBindings();

return springAdvice;
}

这里的东西太多了,所以只挑一个分析:AspectJMethodBeforeAdvice

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

/**
* 封装AspectJ before方法的Spring AOP通知。
*
* @author Rod Johnson
* @author Adrian Colyer
* @since 2.0
*/
@SuppressWarnings("serial")
public class AspectJMethodBeforeAdvice extends AbstractAspectJAdvice implements MethodBeforeAdvice, Serializable {

public AspectJMethodBeforeAdvice(
Method aspectJBeforeAdviceMethod, AspectJExpressionPointcut pointcut, AspectInstanceFactory aif) {

super(aspectJBeforeAdviceMethod, pointcut, aif);
}


@Override
public void before(Method method, Object[] args, @Nullable Object target) throws Throwable {
//首先,获取JoinPointMatch,在被分派到的连接点上获取当前连接点匹配。
//之后调用advice方法。
invokeAdviceMethod(getJoinPointMatch(), null, null);
}

@Override
public boolean isBeforeAdvice() {
//是前置通知
return true;
}

@Override
public boolean isAfterAdvice() {
//不是后置通知
return false;
}

}

先分析到这里,后期还会再分析这个。

到这里所有的Advisors就获取到了。

tencent.jpg