Spring之AOP源码分析

Spring AOP

  • 它基于动态代理来实现。 如果使用接口,用JDK提供给动态代理来实现,如果没有接口,使用CGLIB实现。
  • Spring 3.2以后,spring-core直接把CGLIB和ASM的源码包括进来。
  • Spring AOP需要依赖于IOC容器来管理。
  • Spring提供了AspectJ的支持,但只用到了切点解析和匹配。

源码

开启aop切面

spring通过@EnableAspectJAutoProxy开启aop切面,在注解类上面发现@Import(AspectJAutoProxyRegistrar.class),AspectJAutoProxyRegistrar实现了ImportBeanDefinitionRegistrar,所以他会通过registerBeanDefinitions方法为我们容器导入beanDefinition。
image.png

image.png

image.png

解析切面

image.png
image.png

第一次调用bean的后置处理器回去进行切面的解析。具体解析类是AbstractAutoProxyCreator,它实现了InstantiationAwareBeanPostProcessor。进入postProcessBeforeInstantiation方法。
image.png

判断是否应该跳过。真正的解析是在shouldSkip中。
image.png

image.png

进入findCandidateAdvisors的重写方法。
image.png

调用super.findCandidateAdvisors(),去查找实现了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
kotlin复制代码public List<Advisor> findAdvisorBeans() {

/**
* 探测器字段缓存中cachedAdvisorBeanNames 是用来保存我们的Advisor全类名
* 会在第一个单实例bean的中会去把这个advisor名称解析出来
*/
String[] advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
/**
* 去我们的容器中获取到实现了Advisor接口的实现类
* 而我们的事务注解@EnableTransactionManagement 导入了一个叫ProxyTransactionManagementConfiguration配置类
* 而在这个配置类中配置了
* @Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor();
然后把他的名字获取出来保存到 本类的属性变量cachedAdvisorBeanNames中
*/
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
//若在容器中没有找到,直接返回一个空的集合
if (advisorNames.length == 0) {
return new ArrayList<>();
}

List<Advisor> advisors = new ArrayList<>();
//ioc容器中找到了我们配置的BeanFactoryTransactionAttributeSourceAdvisor
for (String name : advisorNames) {
//判断他是不是一个合适的 是我们想要的
if (isEligibleBean(name)) {
//BeanFactoryTransactionAttributeSourceAdvisor是不是正在创建的bean
if (this.beanFactory.isCurrentlyInCreation(name)) {
if (logger.isDebugEnabled()) {
logger.debug("Skipping currently created advisor '" + name + "'");
}
}
//不是的话
else {
try {
//显示的调用getBean方法方法创建我们的BeanFactoryTransactionAttributeSourceAdvisor返回去
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.isDebugEnabled()) {
logger.debug("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;
}

调用buildAspectJAdvisors去查找注解方式的切面类。

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
kotlin复制代码/**
* 去容器中获取到所有的切面信息保存到缓存中
* @return the list of {@link org.springframework.aop.Advisor} beans
* @see #isEligibleBean
*/
public List<Advisor> buildAspectJAdvisors() {
/**
* 用于保存切面的名称,该地方aspectNames 是我们的类级别的缓存,用户缓存已经解析出来的切面信息
*/
List<String> aspectNames = this.aspectBeanNames;
// 缓存字段aspectNames没有值 会在第一个单例执行后置处理器(AnnotationAwareAspectJAutoProxyCreator注册之后)的时候就会触发解析切面的操作
if (aspectNames == null) {
// 加上同步锁, 防止多线程同时加载Aspect
synchronized (this) {
aspectNames = this.aspectBeanNames;
//做了双重检查加锁
if (aspectNames == null) {
// 保存所有通知的集合
List<Advisor> advisors = new ArrayList<>();
// 保存切面的名称的集合
aspectNames = new ArrayList<>();
/**
* aop功能中在这里传入的是Object.class,代表去容器中获取到所有的组件的名称,然后再经过
* 一一的进行遍历,这个过程是十分的消耗性能的,所以说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注解且不是ajc$开头的文件。
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);
//真正的去获取我们的通知对象 详细看下面getAdvisors方法
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;
}

getAdvisors方法

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
scss复制代码@Override
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)) {
//挨个去解析我们切面中的方法 详细看下面getAdvisor方法
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.
for (Field field : aspectClass.getDeclaredFields()) {
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}

return advisors;
}

getAdvisor方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
scss复制代码public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrderInAspect, String aspectName) {

validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());

// 获得当前通知的 切点表达式 详细看下面getPointcut方法
AspectJExpressionPointcut expressionPointcut = getPointcut(
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
if (expressionPointcut == null) {
return null;
}
// 将切点表达式、 和通知 封装到InstantiationModelAwarePointcutAdvisorImpl对象中 详细看下面InstantiationModelAwarePointcutAdvisorImpl源码
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}

getPointcut方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
typescript复制代码private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
// 找到aspectJ的注解:
// @Pointcut @Around @Before @After @AfterReturning @AfterThrowing
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
// 没有注解那肯定忽略
if (aspectJAnnotation == null) {
return null;
}

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;
}

InstantiationModelAwarePointcutAdvisorImpl函数

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
kotlin复制代码public 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通知对象 详细看下面instantiateAdvice源码
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
}
}

instantiateAdvice方法

1
2
3
4
5
6
kotlin复制代码private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
// 详细看下面getAdvice源码
Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
return (advice != null ? advice : EMPTY_ADVICE);
}

getAdvice源码

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
java复制代码public 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;
}

//判断这里的class对象是不是切面信息对象
if (!isAspect(candidateAspectClass)) {
throw new AopConfigException("Advice must be declared inside an aspect type: " +
"Offending method '" + candidateAdviceMethod + "' in class [" +
candidateAspectClass.getName() + "]");
}
// 记录找到了advice方法
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;

case AtAround: //环绕通知 构建AspectJAroundAdvice
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtBefore: //前置通知 构建AspectJMethodBeforeAdvice
springAdvice = new AspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfter: //后置通知 AspectJAfterAdvice
springAdvice = new AspectJAfterAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfterReturning: //返回通知 AspectJAfterReturningAdvice
springAdvice = new AspectJAfterReturningAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
case AtAfterThrowing: //异常通知 AspectJAfterThrowingAdvice
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);
}

//配置我们构建出来的通知对象
springAdvice.setAspectName(aspectName);
springAdvice.setDeclarationOrder(declarationOrder);
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
if (argNames != null) {
springAdvice.setArgumentNamesFromStringArray(argNames);
}
springAdvice.calculateArgumentBindings();

return springAdvice;
}

applyBeanPostProcessorsBeforeInstantiation到这里第一次调用后置处理器完成了切面的解析那么接下来即调用切面创建动态代理,创建动态代理实在初始化Bean后才调用,即在doCreateBean的时候回去初始化Bean,initializeBean方法中才去调用applyBeanPostProcessorsAfterInitialization方法创建动态代理。

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
typescript复制代码public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {

Object result = existingBean;
//获取我们容器中的所有的bean的后置处理器
for (BeanPostProcessor processor : getBeanPostProcessors()) {
/**
* 在这里是后置处理器的【第九次调用】 aop和事务都会在这里生存代理对象
*
* 【很重要】
* 我们AOP @EnableAspectJAutoProxy 为我们容器中导入了 AnnotationAwareAspectJAutoProxyCreator
* 我们事务注解@EnableTransactionManagement 为我们的容器导入了 InfrastructureAdvisorAutoProxyCreator
* 都是实现了我们的 BeanPostProcessor接口,InstantiationAwareBeanPostProcessor,
* 在这里实现的是BeanPostProcessor接口的postProcessAfterInitialization来生成我们的代理对象
*/
// 详细往下看AbstractAutoProxyCreator实现的postProcessAfterInitialization 方法
Object current = processor.postProcessAfterInitialization(result, beanName);
//若只有有一个返回null 那么直接返回原始的
if (current == null) {
return result;
}
result = current;
}
return result;
}

postProcessAfterInitialization方法(AbstractAutoProxyCreator类实现)

1
2
3
4
5
6
7
8
9
10
11
12
13
less复制代码public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
if (bean != null) {
//获取缓存key
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 之前循环依赖创建的动态代理 如果是现在的bean 就不再创建,,并且移除
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 该方法将会返回动态代理实例
// 详细看wrapIfNecessary源码
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}

wrapIfNecessary方法

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
kotlin复制代码protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//已经被处理过(解析切面时targetSourcedBeans出现过) 就是自己实现创建动态代理逻辑
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
//不需要增强的
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
//是不是基础的bean 是不是需要跳过的 重复判断 ( 因为循环依赖是可以改变bean的,如果把bean改成了advisor呢)
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}

// 根据当前bean找到匹配的advisor
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 当前bean匹配到了advisor
if (specificInterceptors != DO_NOT_PROXY) {
// 标记为已处理
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//创建我们的真正的代理对象
//详细看createProxy方法
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;
}

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
33
34
35
36
37
38
39
40
less复制代码protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable 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代理
// 如果设置了 <aop:aspectj-autoproxy proxy-target-class="true"/>不会进if,说明强制使用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);
// 代表之前是否筛选advise.
// 因为继承了AbstractAdvisorAutoProxyCreator , 并且之前调用了findEligibleAdvisors进行筛选, 所以是true
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
//真正的创建代理对象
return proxyFactory.getProxy(getProxyClassLoader());
}

getProxy方法

1
2
3
4
less复制代码public Object getProxy(@Nullable ClassLoader classLoader) {
//createAopProxy() 用来获取我们的代理工厂
return createAopProxy().getProxy(classLoader);
}

createAopProxy方法

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
arduino复制代码/**
*
* @param config 用来为我们指定我们advisor信息
* 该方法用来创建我们的代理对象
* 所我们的targetClass对象实现了接口,且 ProxyTargetClass 没有指定强制的走cglib代理,那么就是创建jdk代理
* 我们代理的类没有实现接口,那么会直接走cglib代理
* 若我们 ProxyTargetClass 指定为false 且代理类是接口才会走jdk代理 否在我们还是cglib代理
* @return
* @throws AopConfigException
*/
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
//判断我们是否前置指定使用cglib代理ProxyTargetClass =true 或者没有接口
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)) {
return new JdkDynamicAopProxy(config);
}
//cglib代理
return new ObjenesisCglibAopProxy(config);
}
else {
//动态代理
return new JdkDynamicAopProxy(config);
}
}

getProxy方法有两种实现,CGLIB和JDK动态代理。
image.png

到这里就已经创建了AOP动态代理,那么在调用的时候,就会进入到JdkDynamicAopProxyinvoke方法。

invoke方法

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
kotlin复制代码public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
//获取到我们的目标对象
TargetSource targetSource = this.advised.targetSource;
Object target = null;

try {
//若执行代理对象的equals方法不需要代理
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
}
//若执行的是hashCode方法 不需要代理
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
return hashCode();
}
//若执行的class对象是DecoratingProxy 则不会对其应用切面进行方法的增强。返回源目标类型
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// There is only getDecoratedClass() declared -> dispatch to proxy config.
return AopProxyUtils.ultimateTargetClass(this.advised);
}
// 如果目标对象实现的Advised接口,则不会对其应用切面进行方法的增强。 直接执行方法
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}

Object retVal;

/**
* 这个配置很重要很实用【暴露我们的代理对象到线程变量中】需要搭配@EnableAspectJAutoProxy(exposeProxy = true)
* 一起使用.
* 比如我们的aop中 multi和 mode方法都是被切入的方法,但是在切入的方法中通过
* this来调用另外一个方法的时候,那么该方法就不会被代理执行,而是通过方法内部执行
public int mod(int numA,int numB){
System.out.println("执行目标方法:mod");
int retVal = ((Calculate) AopContext.currentProxy()).add(numA,numB);
return retVal%numA;
}
*还有的就是事务方法调用事务方法的时候 也需要这样来社会
*/
if (this.advised.exposeProxy) {
//把我们的代理对象暴露到线程变量中
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}

//获取我们的目标对象
target = targetSource.getTarget();
//获取我们目标对象的class
Class<?> targetClass = (target != null ? target.getClass() : null);

//把我们的aop的advisor 全部转化为拦截器, 通过责任链模式 依此调用
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

//加入我们的拦截器链为空
if (chain.isEmpty()) {
//通过反射直接调用执行
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
//创建一个方法调用对象
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
//调用执行
retVal = invocation.proceed();
}

// Massage return value if necessary.
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this" and the return type of the method
// is type-compatible. Note that we can't help if the target sets
// a reference to itself in another returned object.
retVal = proxy;
}
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
// Must have come from TargetSource.
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}

通过责任链调用。

ReflectiveMethodInvocation的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
kotlin复制代码public Object proceed() throws Throwable {
//从-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;
if (dm.methodMatcher.matches(this.method, this.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 {
//在这个地方需要注意,抵用第一个拦截器的invoke方法,传入的是this 当前的方法拦截器对象
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}

本文转载自: 掘金

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

0%