SpringAOP的原理
SpringAOP的概述和使用已经在之前的文章中讲过,此篇文章就根据一个测试用例简单介绍基于注解的SpringAOP的原理。测试用例如下:
- 导入有关SpringAOP的依赖:
1
2
3
4
5<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>- 编写测试用例如下:
1 |
|
执行结果:
1 | LogUtil前置:add方法开始执行,参数列表为:[1, 1] |
读源码之前先了解一些基础知识:
- 在使用
ApplicationContext
相关实现类加载bean
的时候,会对所有单例且非懒加载的bean
,在构造ApplicationContext
的时候就会初始化好这些bean
,而不会等到使用的时候才去初始化。这也就是单例bean
默认非懒加载的应用。 - 结合以上,被代理后的
bean
,实际在ApplicationContext
构造完成之后就已经被创建完成,getBean()
的操作直接从一级缓存singletonObjects
中获取即可。 beanPostProcessor
和beanFactoryPostProcessor
:beanPostProcessor
接口:bean
后置处理器。beanPostProcessor
能在spring
容器实例化bean
之后,bean
初始化前或后对bean
做一些修改。而aop
的功能实现正式基于此,在bean
初始化后创建针对该bean
的proxy
,然后返回给用户该proxy
。beanFactoryPostProcessor
接口:beanFactoryPostProcessor
接口是针对bean
容器的,它的实现类可以在当前spring
容器加载bean
定义后,bean
实例化之前修改bean
的定义属性,达到影响之后实例化bean
的效果。
spring
中单例bean
的初始化主要过程:createBeanInstance
:实例化,其实也就是调用对象的构造方法实例化对象。populateBean
:填充属性,这一步主要是多bean
的依赖属性进行填充。initializeBean
:初始化,执行该bean
的一些初始化方法。
- 在使用
基于注解的方式实现AOP需要在配置类中添加注解@EnableAspectJAutoProxy。我们就先从这个注解看一下Spring实现AOP的过程,此注解的定义如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public EnableAspectJAutoProxy {
/**
* 控制创建动态代理方式:
* true:①如果目标对象实现了接口则使用CGLIB代理机制。②如果目标对象没有接口(只有实现类)也使用CGLIB代理机制。
* false:①如果目标对象实现了接口则使用JDK动态代理机制(代理所有实现了的接口)。②如果目标对象没有接口(只有实现类)则使用CGLIB代理机制。
*/
boolean proxyTargetClass() default false;
//是否通过aop框架暴露该代理对象。
boolean exposeProxy() default false;
}①从此注解的定义可知其通过@Import(AspectJAutoProxyRegistrar.class)给容器中导入了AspectJAutoProxyRegistrar,通过看源码可知此类是ImportBeanDefinitionRegistrar接口的实现类,即可以利用此组件自定义给容器中注册bean,这里是给利用此组件给容器中注册了一个名为”org.springframework.aop.config.internalAutoProxyCreator”的AnnotationAwareAspectJAutoProxyCreator。
1
2
3
4
5//AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}1
2
3
4
5
6
7//AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null)
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, { Object source)
//向容器中注册AnnotationAwareAspectJAutoProxyCreator。
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}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//AopConfigUtils.registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source)
private static BeanDefinition registerOrEscalateApcAsRequired(
Class<?> cls, BeanDefinitionRegistry registry, { Object source)
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
//如果容器中已经包含internalAutoProxyCreator这个组件。
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
//注册AnnotationAwareAspectJAutoProxyCreator,这里的cls是AnnotationAwareAspectJAutoProxyCreator。
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
//将beanDefinition注册进registry中,注册名为AUTO_PROXY_CREATOR_BEAN_NAME="org.springframework.aop.config.internalAutoProxyCreator"。
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}AnnotationAwareAspectJAutoProxyCreator类的继承树如下图,这里主要关注后置处理器SmartInstantiationAwareBeanPostProcessor和自动装备Bean工厂BeanFactoryAware相关的方法。
首先AnnotationAwareAspectJAutoProxyCreator继承了AbstractAutoProxyCreator实现了BeanFactoryAware接口,所以在创建AnnotationAwareAspectJAutoProxyCreatorBean的过程中初始化方法里面会调用setBeanFactory方法,在setBeanFactory方法里面调用initBeanFactory来初始化通知者检索帮助类,后面检索通知会用到。
1
2
3
4
5
6
7
8
9
10//AbstractAdvisorAutoProxyCreator
public void setBeanFactory(BeanFactory beanFactory) {
super.setBeanFactory(beanFactory);
if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
throw new IllegalArgumentException(
"AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
}
initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
}1
2
3
4//父类AbstractAdvisorAutoProxyCreator中的initBeanFactory方法
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
this.advisorRetrievalHelper = new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {
//重写了父类AbstractAdvisorAutoProxyCreator中的initBeanFactory方法。
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.initBeanFactory(beanFactory);
if (this.aspectJAdvisorFactory == null) {
this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
}
this.aspectJAdvisorsBuilder =
new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
}
}②其次AnnotationAwareAspectJAutoProxyCreator继承了AbstractAutoProxyCreator实现了InstantiationAwareBeanPostProcessor接口,该接口定义了2个方法:postProcessBeforeInstantiation和postProcessAfterInstantiation,所以AbstractAutoProxyCreator实现了这2个方法。在讲Spring启动流程的源码分析里AbstractAutowireCapableBeanFactory.createBean(beanName, mbd, args)中调用了resolveBeforeInstantiation(beanName, mbdToUse)执行了所有实现了InstantiationAwareBeanPostProcessor接口的类的postProcessBeforeInstantiation方法。
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//AbstractAutoProxyCreator类实现InstantiationAwareBeanPostProcessor接口中的方法。
/**
* 在创建Bean的流程中还没调用构造器来实例化Bean的时候进行调用
* AOP解析切面以及事务解析事务注解都是在这里完成的
* @param beanClass 当前正在创建的Bean的Class对象
* @param beanName beanName
* @return
* @throws BeansException
*/
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
//构建我们的缓存key
Object cacheKey = getCacheKey(beanClass, beanName);
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
//如果被解析过直接返回
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
/**
* 判断是不是基础的Bean(Advice、PointCut、Advisor、AopInfrastructureBean)是就直接跳过
* 判断是不是应该跳过 (AOP解析直接解析出我们的切面信息(并且把我们的切面信息进行缓存),而事务在这里是不会解析的)
*/
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;
}如果有返回值则触发BeanPostProcessor.postProcessAfterInitialization()方法。
1
2
3
4
5
6
7
8
9
10
11//AbstractAutoProxyCreator类实现BeanPostProcessor接口中的方法。
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;
}③通过测试用例的debug分析运行流程:
①传入配置类,创建ioc容器(new AnnotationConfigApplicationContext(MainConfig.class))。
1
2
3
4
5
6
7
8public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
//调用无参构造创建对象。
this();
//注册配置类。
register(componentClasses);
//刷新容器,初始化容器创建需要的bean。
refresh();
}②注册配置类后调用refresh()刷新容器。refresh()方法调用方法registerBeanPostProcessors(beanFactory),即注册BeanPostProcessor(Bean的后置处理器),用于拦截bean创建过程。此方法完成了AnnotationAwareAspectJAutoProxyCreator的注册。
- ①先获取ioc容器已经定义了的需要创建对象的所有BeanPostProcessor。
- ②向容器中注册后置处理器BeanPostProcessorChecker。
- ③先注册实现了PriorityOrdered接口的BeanPostProcessor。
- ④再给容器中注册实现了Ordered接口的BeanPostProcessor。
- ⑤注册没实现优先级接口的BeanPostProcessor。
- ⑥最后重新注册所有内部BeanPostProcessor。
③AnnotationAwareAspectJAutoProxyCreator的注册是在上述第大③步的registerBeanPostProcessors(beanFactory)方法中完成的,由继承关系可知其实现了Ordered接口,所以是在上述第②大步中的第④小步中完成的。
①getBean(ppName, BeanPostProcessor.class)方法通过调用doGetBean(name, requiredType, null, false)—>getSingleton()—>createBean(beanName, mbd, args)—>doCreateBean(beanName, mbdToUse, args)方法,可见创建此后置处理器的实例重点在doCreateBean(beanName, mbdToUse, args)方法:
①创建Bean的实例。
②给bean的各种属性赋值。
③初始化bean。
①处理Aware接口的方法回调,此时执行之前打断点处的AbstractAdvisorAutoProxyCreator.setBeanFactory方法。
1
2
3
4
5
6
7
8
9
public void setBeanFactory(BeanFactory beanFactory) {
super.setBeanFactory(beanFactory);
if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
throw new IllegalArgumentException(
"AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
}
initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
}
紧接着调用AnnotationAwareAspectJAutoProxyCreator.initBeanFactory(beanFactory)方法。
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);
}②执行后置处理器初始化之前的方法(postProcessBeforeInitialization())。
③执行自定义的初始化方法。
④执行后置处理器初始化之后的方法(postProcessAfterInitialization())。
②至此beanFactory.getBean(ppName, BeanPostProcessor.class)执行成功,接下来将注册和初始化成功的AnnotationAwareAspectJAutoProxyCreator注册到BeanFactory中(registerBeanPostProcessors(beanFactory, orderedPostProcessors))。
1
2
3
4
5
6
7
8
9
10
11
12List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
//按照优先级排序。
sortPostProcessors(orderedPostProcessors, beanFactory);
//注册到容器中。
registerBeanPostProcessors(beanFactory, orderedPostProcessors);1
2
3
4
5
6
7private static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
for (BeanPostProcessor postProcessor : postProcessors) {
beanFactory.addBeanPostProcessor(postProcessor);
}
}
④注册完BeanPostProcessor后,refresh()还调用了方法finishBeanFactoryInitialization(beanFactory) ,创建剩下的单实例bean。
①调用DefaultListableBeanFactory.preInstantiateSingletons()方法,遍历获取容器中所有的Bean,实例化所有剩余的(非懒加载初始化)单例bean。
②调用getBean(beanName)方法创建bean实例,此方法的执行过程还是调用doGetBean(name, requiredType, null, false)—>getSingleton()—>createBean(beanName, mbd, args)—>doCreateBean(beanName, mbdToUse, args)完成。在此过程中的createBean(beanName, mbd, args)调用了resolveBeforeInstantiation(beanName, mbdToUse),即让BeanPostProcessor有机会返回代理而不是目标bean实例。
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
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
// 确保此时bean类已经被解析。
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
//拿到所有后置处理器,如果是InstantiationAwareBeanPostProcessor,就执行postProcessBeforeInstantiation。
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
//如果有返回值则触发postProcessAfterInitialization()。
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//执行InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation方法。
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
//执行BeanPostProcessor.postProcessAfterInitialization方法。
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}postProcessBeforeInstantiation方法是InstantiationAwareBeanPostProcessor接口中定义的方法,其会在applyBeanPostProcessorsBeforeInstantiation方法中被调用,同时也是在创建Bean实例之前先尝试用后置处理器返回对象的。而BeanPostProcessor是在Bean对象创建完成初始化前后调用的。
③这时通过上面的applyBeanPostProcessorsBeforeInstantiation方法执行InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()方法,即来到我们一开始打好断点的AbstractAutoProxyCreator类中的postProcessBeforeInstantiation()方法。即开始了Spring创建AOP代理的步骤。现在通过debug来到mathCalculator的创建。
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
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
Object cacheKey = getCacheKey(beanClass, beanName);
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
//判断当前bean是否在advisedBeans中(advisedBeans保存了所有需要增强的bean)。
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
//判断当前bean是否基础类型Advice、Pointcut、Advisor、AopInfrastructureBean,或是否切面(@Aspect)的。而且判断是否需要跳过。
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 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;
}①判断当前bean是否在advisedBeans中(advisedBeans保存了所有需要增强的bean)。
②判断当前bean是否基础类型Advice、Pointcut、Advisor、AopInfrastructureBean,或是否切面(@Aspect)的,这里返回false。
③判断是否需要跳过(shouldSkip(beanClass, beanName)),这里也返回false。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
// TODO: Consider optimization by caching the list of the aspect names
//获取候选的增强器(切面里面的通知方法),即把当前切面里的四个通知方法包装成四个增强器List<Advisor> candidateAdvisors。增强器的类型为InstantiationModelAwarePointcutAdvisor。
List<Advisor> candidateAdvisors = findCandidateAdvisors();
//判断每一个增强器是否是AspectJPointcutAdvisor类型的。
for (Advisor advisor : candidateAdvisors) {
if (advisor instanceof AspectJPointcutAdvisor &&
((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
return true;
}
}
//返回false。
return super.shouldSkip(beanClass, beanName);
}①调用findCandidateAdvisors()获取候选的增强器(切面里面的通知方法),即把当前切面里的四个通知方法包装成四个增强器List<Advisor> candidateAdvisors。且增强器的类型为InstantiationModelAwarePointcutAdvisor。
1
2
3
4
5
6
7
8
9
10
11
protected List<Advisor> findCandidateAdvisors() {
//找出事务相关的advisor
List<Advisor> advisors = super.findCandidateAdvisors();
//找出Aspect相关的信息之后封装为一个advisor
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
//返回我们所有的通知
return advisors;
}①调用super.findCandidateAdvisors()找出事务相关的advisor。
1
2
3
4
5protected List<Advisor> findCandidateAdvisors() {
Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
//通过通知者检测帮助类来帮助我们找到通知
return this.advisorRetrievalHelper.findAdvisorBeans();
}②调用this.aspectJAdvisorsBuilder.buildAspectJAdvisors()找出Aspect相关的信息之后封装为一个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
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/**
* 去容器中获取到所有的切面信息保存到缓存中
**/
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;
//缓存字段aspectNames没有值,注意实例化第一个单实例bean的时候就会触发解析切面
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
//用于保存所有解析出来的Advisors集合对象
List<Advisor> advisors = new ArrayList<>();
//用于保存切面的名称的集合
aspectNames = new ArrayList<>();
/**
* AOP功能中在这里传入的是Object对象,代表去容器中获取到所有的组件的名称,然后再
* 进行遍历,这个过程是十分的消耗性能的,所以说Spring会再这里加入了保存切面信息的缓存。
* 但是事务功能不一样,事务模块的功能是直接去容器中获取Advisor类型的,选择范围小,且不消耗性能。
* 所以Spring在事务模块中没有加入缓存来保存我们的事务相关的advisor
*/
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
//遍历我们从IOC容器中获取处的所有Bean的名称
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
}
//通过beanName去容器中获取到对应class对象
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
//根据class对象判断是不是切面 @Aspect
if (this.advisorFactory.isAspect(beanType)) {
//是切面类
//加入到缓存中
aspectNames.add(beanName);
//把beanName和class对象构建成为一个AspectMetadata
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
//构建切面注解的实例工厂
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
//真正的去获取我们的Advisor
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();
}
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;
}①调用this.advisorFactory.isAspect(beanType)根据class对象判断是不是切面 @Aspect。
1
2
3
4
public boolean isAspect(Class<?> clazz) {
return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz));
}1
2
3private boolean hasAspectAnnotation(Class<?> clazz) {
return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null);
}②真正的去获取我们的Advisor,this.advisorFactory.getAdvisors(factory)方法如下。
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
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
//获取我们的标记为Aspect的类
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
//获取我们的切面类的名称
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
//校验我们的切面类
validate(aspectClass);
//我们使用的是包装模式来包装我们的MetadataAwareAspectInstanceFactory构建为MetadataAwareAspectInstanceFactory
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
List<Advisor> advisors = new ArrayList<>();
//获取到切面类中的所有方法,但是该方法不会解析到标注了@PointCut注解的方法
for (Method method : getAdvisorMethods(aspectClass)) {
//循环解析我们切面中的方法
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
if (advisor != null) {
advisors.add(advisor);
}
}
if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);
}
for (Field field : aspectClass.getDeclaredFields()) {
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}这里面会调用getAdvisorMethods(aspectClass)获取切面上的通知方法,并按照规则排序。
1
2
3
4
5
6
7
8
9
10
11
12
13private List<Method> getAdvisorMethods(Class<?> aspectClass) {
final List<Method> methods = new ArrayList<>();
ReflectionUtils.doWithMethods(aspectClass, method -> {
// Exclude pointcuts
if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
methods.add(method);
}
}, ReflectionUtils.USER_DECLARED_METHODS);
if (methods.size() > 1) {
methods.sort(METHOD_COMPARATOR);
}
return methods;
}排序的规则如下:
接着会调用getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName)一一根据切面方法创建增强器。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
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
46public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
//当前的切点表达式
this.declaredPointcut = declaredPointcut;
//切面的class对象
this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
//切面方法的名称
this.methodName = aspectJAdviceMethod.getName();
//切面方法的参数类型
this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
//切面方法对象
this.aspectJAdviceMethod = aspectJAdviceMethod;
//aspectj的通知工厂
this.aspectJAdvisorFactory = aspectJAdvisorFactory;
//aspect的实例工厂
this.aspectInstanceFactory = aspectInstanceFactory;
//切面的顺序
this.declarationOrder = declarationOrder;
//切面的名称
this.aspectName = aspectName;
/**
* 判断当前的切面对象是否需要延时加载
*/
if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
// Static part of the pointcut is a lazy type.
Pointcut preInstantiationPointcut = Pointcuts.union(
aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
// Make it dynamic: must mutate from pre-instantiation to post-instantiation state.
// If it's not a dynamic pointcut, it may be optimized out
// by the Spring AOP infrastructure after the first evaluation.
this.pointcut = new PerTargetInstantiationModelPointcut(
this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
this.lazy = true;
}
else {
// A singleton aspect.
this.pointcut = this.declaredPointcut;
this.lazy = false;
//将切面中的通知构造为advice通知对象
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
}
}里面通过调用instantiateAdvice(this.declaredPointcut)将切面中的通知构造为advice通知对象:
1
2
3
4
5private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
return (advice != null ? advice : EMPTY_ADVICE);
}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
85public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
//获取我们的切面类的class对象
Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
validate(candidateAspectClass);
//获取切面方法上的注解
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
//解析出来的注解信息是否为null
if (aspectJAnnotation == null) {
return null;
}
//再次判断是否是切面对象
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()) {
//是PointCut注解 那么就抛出异常 因为在外面传递进来的方法已经排除了Pointcut的方法
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
//环绕通知 构建AspectJAroundAdvice
case AtAround:
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
//前置通知 构建AspectJMethodBeforeAdvice
case AtBefore:
springAdvice = new AspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
//后置通知 AspectJAfterAdvice
case AtAfter:
springAdvice = new AspectJAfterAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
//返回通知 AspectJAfterReturningAdvice
case AtAfterReturning:
springAdvice = new AspectJAfterReturningAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
//异常通知 AspectJAfterThrowingAdvice
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);
}
//设置我们构建出来的通知对象的相关属性比如DeclarationOrder,在代理调用的时候,责任链顺序上会用到
springAdvice.setAspectName(aspectName);
springAdvice.setDeclarationOrder(declarationOrder);
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
if (argNames != null) {
springAdvice.setArgumentNamesFromStringArray(argNames);
}
springAdvice.calculateArgumentBindings();
return springAdvice;
}
③到此所有的切面方法解析完成,如果该切面是单实例的就加入到缓存中。
1
2
3
4
5
6
7if (this.beanFactory.isSingleton(beanName)) {
this.advisorsCache.put(beanName, classAdvisors);
}
else {
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);④遍历所有的切面,将每个切面的所有的增强器添加在advisors中进行返回。
1
2
3
4
5
6
7
8
9
10
11
12List<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;
②判断每一个增强器是否是AspectJPointcutAdvisor类型的,如果是则返回true,由于这里的四个增强器都是InstantiationModelAwarePointcutAdvisor类型的,所以永远返回false。
1
2
3
4
5
6for (Advisor advisor : candidateAdvisors) {
if (advisor instanceof AspectJPointcutAdvisor &&
((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
return true;
}
}③最后调用父类的shouldSkip()返回false,就是不跳过的意思。
④如果我们有一个自定义TargetSource,则在这里创建代理并返回。至此postProcessBeforeInstantiation执行完成。
④这时通过上面的applyBeanPostProcessorsAfterInitialization方法执行BeanPostProcessor.postProcessAfterInitialization()方法,即来到我们一开始打好断点的AbstractAutoProxyCreator.postProcessAfterInitialization()方法,其主要就是通过前面创建的增强器来创建代理对象。
1
2
3
4
5
6
7
8
9
10
11
12
public Object postProcessAfterInitialization( { Object bean, String beanName)
if (bean != null) {
//获取缓存key
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
//如果有必要就代理
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}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
34protected 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;
}
//是不是基础的bean 是不是需要跳过的
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
//获取当前bean的所有增强器(通知方法)。
//如果有匹配的通知,就创建代理对象
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
//如果当前bean需要增强,则进入创建代理对象的过程。
if (specificInterceptors != DO_NOT_PROXY) {
//设置当前的对象已处理
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//创建代理对象。
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;
}①获取当前bean的所有增强器(通知方法) :Object[] specificInterceptors。
1
2
3
4
5
6
7
8
9
10
11
12
protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, TargetSource targetSource) {
//找合适的增强器对象
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
//若为空表示没找到
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}①获取到能在bean使用的增强器。
②给增强器排序。
1
2
3
4
5
6
7
8
9
10
11
12protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
//获取所有可用的增强器。
List<Advisor> candidateAdvisors = findCandidateAdvisors();
//获取当前bean可用的增强器。
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
//给增强器排序。
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}1
2
3
4
5
6
7
8
9
10
11
12protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
//从候选的通知器中找到合适正在创建的实例对象的通知器
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
}
finally {
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}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//AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
//若候选的增强器集合为空 直接返回
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
//定义一个合适的增强器集合对象
List<Advisor> eligibleAdvisors = new ArrayList<>();
//循环我们候选的增强器对象
for (Advisor candidate : candidateAdvisors) {
//判断我们的增强器对象是不是实现了IntroductionAdvisor (很明显我们事务的没有实现 所以不会走下面的逻辑)
if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
}
}
//不为空
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
for (Advisor candidate : candidateAdvisors) {
//判断我们的增强器对象是不是实现了IntroductionAdvisor (很明显我们事务的没有实现 所以不会走下面的逻辑)
if (candidate instanceof IntroductionAdvisor) {
// already processed
//在上面已经处理过 ,不需要处理
continue;
}
//真正的判断增强器是否合适当前类型
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18//AopUtils.canApply(candidate, clazz, hasIntroductions)
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
//判断我们的增强器是否是IntroductionAdvisor
if (advisor instanceof IntroductionAdvisor) {
return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
}
//判断我们事务的增强器BeanFactoryTransactionAttributeSourceAdvisor是否实现了PointcutAdvisor
else if (advisor instanceof PointcutAdvisor) {
//转为PointcutAdvisor类型
PointcutAdvisor pca = (PointcutAdvisor) advisor;
//找到真正能用的增强器
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
}
else {
// It doesn't have a pointcut so we assume it applies.
return true;
}
}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
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
Assert.notNull(pc, "Pointcut must not be null");
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}
//通过切点获取到一个方法匹配器对象
MethodMatcher methodMatcher = pc.getMethodMatcher();
if (methodMatcher == MethodMatcher.TRUE) {
// No need to iterate the methods if we're matching any method anyway...
return true;
}
//判断匹配器是不是IntroductionAwareMethodMatcher
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
}
//创建一个集合用于保存targetClass的class对象
Set<Class<?>> classes = new LinkedHashSet<>();
//判断当前class是不是代理的class对象
if (!Proxy.isProxyClass(targetClass)) {
//加入到集合中去
classes.add(ClassUtils.getUserClass(targetClass));
}
//获取到targetClass所实现的接口的class对象,然后加入到集合中
classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
//循环所有的class对象
for (Class<?> clazz : classes) {
//通过class获取到所有的方法
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
//循环我们的方法
for (Method method : methods) {
//通过methodMatcher.matches来匹配我们的方法
if (introductionAwareMethodMatcher != null ?
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}
②如果当前bean需要增强,则将进入创建代理对象的过程。当前的bean为mathCalculator,需要增强。
③保存当前bean在advisedBeans中。
④创建当前bean的代理对象,即调用createProxy()方法。
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
33protected Object createProxy(Class<?> beanClass, String beanName,
{ Object[] specificInterceptors, TargetSource targetSource)
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
//创建一个代理对象工厂
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
//为proxyFactory设置创建jdk还是cglib代理
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
//把我们的specificInterceptors数组中的Advisor转化为数组形式的
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
//保存到代理工厂。
proxyFactory.addAdvisors(advisors);
//设置targetSource对象
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
//创建代理对象。
return proxyFactory.getProxy(getProxyClassLoader());
}①获取当前bean的所有增强器(通知方法)。
②保存到proxyFactory。
③创建代理对象proxyFactory.getProxy(getProxyClassLoader()。
JdkDynamicAopProxy(config):jdk动态代理。
ObjenesisCglibAopProxy(config):cglib的动态代理。
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//此方法在ProxyFactory类中。
public Object getProxy( { ClassLoader classLoader)
return createAopProxy().getProxy(classLoader);
}
//此方法在ProxyCreatorSupport类中。
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
//此方法在DefaultAopProxyFactory类中。
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
//判断我们是否指定使用cglib代理ProxyTargetClass =true 默认false
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
//targetClass是接口使用的就是jdk代理
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
//创建JDK动态代理(基于接口)。
return new JdkDynamicAopProxy(config);
}
//创建CGLIB的动态代理(基于类)
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
④返回代理对象。由于上面测试用例中的MathCalculator没有实现任何接口,因此在默认情况下Spring使用的是基于CGLIB的动态代理。以后容器中获取到的就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程。
⑤创建代理对象成功并返回后,现在回到测试用例,debug目标方法的执行过程。
①目标方法执行时,会先进入CglibAopProxy类的intercept方法。
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
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
//获取到我们的目标对象
TargetSource targetSource = this.advised.getTargetSource();
try {
//这个配置是暴露我们的代理对象到线程变量中,需要搭配@EnableAspectJAutoProxy(exposeProxy = true)一起使用,比如在目标对象方法中再次获取代理对象可以使用这个AopContext.currentProxy(),还有的就是事务方法调用事务方法的时候也是用到这个
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
//把我们的代理对象暴露到线程变量中
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...
//目标对象,也就是切入点对象。
target = targetSource.getTarget();
//获取我们目标对象的class
Class<?> targetClass = (target != null ? target.getClass() : null);
//把aop的advisor转化为拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
// Check whether we only have one InvokerInterceptor: that is,
// no real advice, but just reflective invocation of the target.
//如果没有拦截器链。
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
// We can skip creating a MethodInvocation: just invoke the target directly.
// Note that the final invoker must be an InvokerInterceptor, so we know
// it does nothing but a reflective operation on the target, and no hot
// swapping or fancy proxying.
//通过反射直接调用执行
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
// 直接执行目标方法。
retVal = methodProxy.invoke(target, argsToUse);
}
else {
//如果有拦截器链则把需要执行的目标对象,目标方法,拦截器链等信息传入并创建一个CglibMethodInvocation对象,最后调用其proceed()方法。
// We need to create a method invocation...
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}①根据ProxyFactory对象获取将要执行的目标方法拦截器链(每一个通知方法又被包装为方法拦截器,后来每个方法的执行都是利用MethodInterceptor机制)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16//此方法在AdvisedSupport类中。
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, { Class<?> targetClass)
//缓存目标方法。
MethodCacheKey cacheKey = new MethodCacheKey(method);
//获取缓存中目标方法的拦截器链。
List<Object> cached = this.methodCache.get(cacheKey);
//缓存中没有获取到拦截器链。
if (cached == null) {
//获取目标方法的拦截器链。
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, method, targetClass);
this.methodCache.put(cacheKey, cached);
}
return cached;
}
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//此方法在DefaultAdvisorChainFactory类中。
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, { Class<?> targetClass)
// This is somewhat tricky... We have to process introductions first,
// but we need to preserve order in the ultimate list.
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
Advisor[] advisors = config.getAdvisors();
//保存所有拦截器。
List<Object> interceptorList = new ArrayList<>(advisors.length);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
Boolean hasIntroductions = null;
//遍历所有增强器。
for (Advisor advisor : advisors) {
//如果是切入点增强器。
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
boolean match;
if (mm instanceof IntroductionAwareMethodMatcher) {
if (hasIntroductions == null) {
hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
}
match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
}
else {
match = mm.matches(method, actualClass);
}
if (match) {
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
if (mm.isRuntime()) {
// Creating a new object instance in the getInterceptors() method
// isn't a problem as we normally cache created chains.
for (MethodInterceptor interceptor : interceptors) {
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
}
else {
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
else if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
else {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
return interceptorList;
}①通过List<Object> interceptorList保存所有拦截器,此时长度为5(一个默认的ExposeInvocationInterceptor和4个增强器)。
②遍历所有的增强器,将其转为Interceptor,即调用registry.getInterceptors(advisor)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22//此方法在DefaultAdvisorAdapterRegistry类中。
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List<MethodInterceptor> interceptors = new ArrayList<>(3);
Advice advice = advisor.getAdvice();
//如果advice增强器是MethodIntercept类型。
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
//遍历适配器。
for (AdvisorAdapter adapter : this.adapters) {
//适配器类型与增强器类型匹配。
if (adapter.supportsAdvice(advice)) {
//将增强器装换成MethodIntercept类型。
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return interceptors.toArray(new MethodInterceptor[0]);
}①如果是MethodInterceptor,直接加入到集合中。
②如果不是,使用AdvisorAdapter将增强器转为MethodInterceptor。适配器内容如下图:
③转换完成返回MethodInterceptor数组。
②如果没有拦截器链,直接执行目标方法。
③如果有拦截器链则把需要执行的目标对象,目标方法,拦截器链等信息传入并创建一个CglibMethodInvocation对象,最后调用其proceed()方法。
④再创建了一个CglibMethodInvocation()对象后,通过调用proceed()实现目标方法的调用。
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//此方法在CglibAopProxy类中。
public Object proceed() throws Throwable {
try {
return super.proceed();
}
catch (RuntimeException ex) {
throw ex;
}
catch (Exception ex) {
if (ReflectionUtils.declaresException(getMethod(), ex.getClass())) {
throw ex;
}
else {
throw new UndeclaredThrowableException(ex);
}
}
}
//此方法在ReflectiveMethodInvocation类中。
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
//this.currentInterceptorIndex初始值为-1,用于记录拦截器的索引。
//或者拦截器的索引和拦截器数组-1大小一样(指定到了最后一个拦截器)
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
//执行目标方法。
return invokeJoinpoint();
}
//从拦截器链中获取拦截器。
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
//如果获取的拦截器是动态匹配方法拦截器类型。
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
// 动态匹配失败。跳过这个拦截器并调用链中的下一个。
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
// 调用拦截器:切入点将在构造这个对象之前被静态地计算。
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
+ ①链式获取每一个拦截器,拦截器执行invoke方法,每一个拦截器等待下一个拦截器执行完成返回以后再来执行(递归调用),**拦截器链的机制,保证通知方法与目标方法的执行顺序**。五个拦截器的信息如下:
{% asset_img 12.png %}
+ ①ExposeInvocationInterceptor的invoke方法:
```java
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
MethodInvocation oldInvocation = invocation.get();
invocation.set(mi);
try {
return mi.proceed();
}
finally {
invocation.set(oldInvocation);
}
}②AspectJAfterThrowingAdvice的invoke方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
catch (Throwable ex) {
if (shouldInvokeOnThrowing(ex)) {
//执行异常通知。
invokeAdviceMethod(getJoinPointMatch(), null, ex);
}
throw ex;
}
}③AfterReturningAdviceInterceptor的invoke方法:
1
2
3
4
5
6
7
public Object invoke(MethodInvocation mi) throws Throwable {
//如果此方法执行后没有异常则直接执行返回通知;如果有异常则抛给上个拦截器。
Object retVal = mi.proceed();
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}④AspectJAfterAdvice的invoke方法:
1
2
3
4
5
6
7
8
9
10
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
finally {
//执行后置通知。
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}⑤MethodBeforeAdviceInterceptor的invoke方法:
1
2
3
4
5
6
public Object invoke(MethodInvocation mi) throws Throwable {
//调用前置通知。
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
return mi.proceed();
}图解:
总结:
通过@EnableAspectJAutoProxy注解开启AOP功能,该注解为我们Spring容器中注册了AnnotationAwareAspectJAuto ProxyCreator组件,AOP的准备和代理创建都在这个组件中完成,AnnotationAwareAspectJAutoProxyCreator继承AbstractAuto ProxyCreator实现了InstantiationAwareBeanPostProcessor接口,在方法postProcessBeforeInstantiation中找到Spring容器中所有的增强器,为创建代理做准备;AnnotationAwareAspectJAutoProxyCreator继承了AbstractAutoProxyCreator实现了BeanPost Processor接口,在方法postProcessAfterInitialization中通过前面找到的候选增强器中找到合适的增强器来创建代理对象,最后调用目标方法,进去到代理对象的invoke方法中进行调用。
- @EnableAspectJAutoProxy 开启AOP功能。
- @EnableAspectJAutoProxy 会给容器中注册一个组件 AnnotationAwareAspectJAutoProxyCreator,它是一个后置处理器。
- 容器的创建流程:
- registerBeanPostProcessors()注册后置处理器,创建AnnotationAwareAspectJAutoProxyCreator对象。
- finishBeanFactoryInitialization()初始化剩下的单实例bean。
- 创建业务逻辑组件和切面组件。
- AnnotationAwareAspectJAutoProxyCreator拦截组件的创建过程。
- 组件创建完之后,判断组件是否需要增强(如果是则把切面的通知方法包装成增强器(Advisor),给业务逻辑组件创建一个代理对象(cglib))。
- 执行目标方法:
- 代理对象执行目标方法。
- CglibAopProxy.intercept():
- 得到目标方法的拦截器链(增强器包装成拦截器MethodInterceptor)。
- 利用拦截器的链式机制,依次进入每一个拦截器进行执行。
- 正常执行:前置通知–>目标方法–>后置通知–>返回通知。
- 出现异常:前置通知–>目标方法–>后置通知–>异常通知。