SpringAOP 源码之 bean 创建

AspectJAwareAdvisorAutoProxyCreator

img

定位: org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator

AbstractAutoProxyCreator

getEarlyBeanReference

定位: org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#getEarlyBeanReference

三级缓存使用到

1
2
3
4
5
6
7
8
9
/**  
* 放到集合中,然后判断要不要包装,其实就是在循环依赖注入属性的时候如果有AOP代理的话,也会进行代理,然后返回
*/
@Override
public Object getEarlyBeanReference(Object bean, String beanName) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
this.earlyProxyReferences.put(cacheKey, bean);
return wrapIfNecessary(bean, beanName, cacheKey);
}

postProcessBeforeInstantiation

定位: org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessBeforeInstantiation

bean 实例化之前, 对 自定义的 TargetSource 进行代理

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
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
Object cacheKey = getCacheKey(beanClass, beanName);

if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
//查缓存,是否有处理过了,不管是不是需要通知增强的,只要处理过了就会放里面
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
// 要跳过的直接设置FALSE
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,请在此处创建代理;抑制不必要的目标bean的默认实例化, 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;
}

postProcessAfterInitialization

定位: org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization

初始化完成后创建代理对象

1
2
3
4
5
6
7
8
9
10
11
12
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
// 获取当前 bean 的缓存 key:如果 beanName 不为空,则以 beanName 为 key,如果为FactoryBean 类型,前面会添加 & 符号;如果 beanName 为空,则以当前 bean 对应的 class 为 key
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 判断当前 bean 是否正在被代理,如果正在被代理则不进行封装
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 如果它需要被代理,则需要封装指定的 bean
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}

wrapIfNecessary

定位: org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary

先判断是否已经处理过,是否需要跳过,跳过的话直接就放进advisedBeans里,表示不进行代理,如果这个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
/**
*
*/
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 如果已经处理过,直接返回
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
// 这里 advisedBeans 缓存了已经进行了代理的 bean ,如果缓存中存在,则可以直接返回
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
// 这里 isInfrastructureClass() 用于判断当前 bean 是否为 Spring 容器内部的 bean,内部的bean 是不用进行代理的;shouldSkip() 则用于判断当前 bean 是否应该被跳过
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
// 对当前bean进行缓存
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}

// Create proxy if we have advice.
// 获取当前 bean 的 Advices 和 Advisors
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 对当前bean的代理状态进行缓存
if (specificInterceptors != DO_NOT_PROXY) {
// 对当前 bean 的代理状态进行缓存
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 根据获取到的Advices和Advisors为当前bean生成代理对象
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
// 缓存生成的代理bean的类型,并且返回生成的代理bean
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}

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

createProxy

定位: org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy

进行代理工厂的创建,然后判断是否需要设置 proxyTargetClass,以便于后面决定是不是要进行 jdk动态代理还是 cglib 的动态代理, 然后把通知器 advisors 包装下,加入到代理工厂,获取代理对象

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
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {

// 给bean定义设置暴露属性
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}

// 创建代理工厂
ProxyFactory proxyFactory = new ProxyFactory();
// 获取当前类中相关属性
proxyFactory.copyFrom(this);
// 决定对于给定的bean是否应该使用targetClass而不是他的接口代理,检查proxyTargetClass设置以及preserverTargetClass属性
if (!proxyFactory.isProxyTargetClass()) {
// 判断是 使用jdk动态代理 还是cglib代理
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
// 添加代理接口
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}

// 构建增强器
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
// 设置到要代理的类
proxyFactory.setTargetSource(targetSource);
// 定制代理
customizeProxyFactory(proxyFactory);

// 控制代理工厂被配置之后,是否还允许修改通知,默认值是 false
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 真正创建代理对象
return proxyFactory.getProxy(getProxyClassLoader());
}


protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
// Handle prototypes correctly...
// 解析注册的所有interceptorName
Advisor[] commonInterceptors = resolveInterceptorNames();

List<Object> allInterceptors = new ArrayList<>();
if (specificInterceptors != null) {
// 加入拦截器
allInterceptors.addAll(Arrays.asList(specificInterceptors));
if (commonInterceptors.length > 0) {
if (this.applyCommonInterceptorsFirst) {
allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
}
else {
allInterceptors.addAll(Arrays.asList(commonInterceptors));
}
}
}
if (logger.isTraceEnabled()) {
int nrOfCommonInterceptors = commonInterceptors.length;
int nrOfSpecificInterceptors = (specificInterceptors != null ? specificInterceptors.length : 0);
logger.trace("Creating implicit proxy for bean '" + beanName + "' with " + nrOfCommonInterceptors +
" common interceptors and " + nrOfSpecificInterceptors + " specific interceptors");
}

Advisor[] advisors = new Advisor[allInterceptors.size()];
for (int i = 0; i < allInterceptors.size(); i++) {
// 拦截器进行封装转化为Advisor
advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
}
return advisors;
}

advisorAdapterRegistry#wrap

org.springframework.aop.framework.adapter.DefaultAdvisorAdapterRegistry#wrap

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
@Override
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
// 如果要封装的对象本身就是Advisor类型,那么无须做任何处理
if (adviceObject instanceof Advisor) {
return (Advisor) adviceObject;
}
// 如果类型不是 Advisor 和 Advice 两种类型的数据,那么将不能进行封装
if (!(adviceObject instanceof Advice)) {
throw new UnknownAdviceTypeException(adviceObject);
}
Advice advice = (Advice) adviceObject;
if (advice instanceof MethodInterceptor) {
// So well-known it doesn't even need an adapter.
// 如果是 MethodInterceptor 类型则使用 DefaultPointcutAdvisor 封装
return new DefaultPointcutAdvisor(advice);
}
// 如果存在 Advisor 的适配器那么也同样需要进行封装
for (AdvisorAdapter adapter : this.adapters) {
// Check that it is supported.
// 默认支持这 3 种 MethodBeforeAdviceAdapter / AfterReturningAdviceAdapter / ThrowsAdviceAdapter
if (adapter.supportsAdvice(advice)) {
return new DefaultPointcutAdvisor(advice);
}
}
throw new UnknownAdviceTypeException(advice);
}

ProxyProcessorSupport

定位: org.springframework.aop.framework.ProxyProcessorSupport

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
/**
* 判断接口是不是需要设置 ProxyTargetClass = true,判断它的接口不是内部的回调接口和内部语言接口,就添加接口否则就设置 ProxyTargetClass = true
*/
protected void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) {
Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader());
boolean hasReasonableProxyInterface = false;
for (Class<?> ifc : targetInterfaces) {
if (!isConfigurationCallbackInterface(ifc) && !isInternalLanguageInterface(ifc) &&
ifc.getMethods().length > 0) {
// 用接口代理,也就是jdk
hasReasonableProxyInterface = true;
break;
}
}
// 有接口
if (hasReasonableProxyInterface) {
// Must allow for introductions; can't just set interfaces to the target's interfaces only.
for (Class<?> ifc : targetInterfaces) {
proxyFactory.addInterface(ifc);
}
}
else {
// 没接口就设置 true
proxyFactory.setProxyTargetClass(true);
}
}
/**
* 判断是不是 Spring 容器内部的接口
*
*/
protected boolean isConfigurationCallbackInterface(Class<?> ifc) {
return (InitializingBean.class == ifc || DisposableBean.class == ifc || Closeable.class == ifc ||
AutoCloseable.class == ifc || ObjectUtils.containsElement(ifc.getInterfaces(), Aware.class));
}
/**
* 判断是不是一些已知的内部语言接口
*/
protected boolean isInternalLanguageInterface(Class<?> ifc) {
return (ifc.getName().equals("groovy.lang.GroovyObject") ||
ifc.getName().endsWith(".cglib.proxy.Factory") ||
ifc.getName().endsWith(".bytebuddy.MockAccess"));
}

AbstractAdvisorAutoProxyCreator

getAdvicesAndAdvisorsForBean

定位: org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean

1
2
3
4
5
6
7
8
9
10
11
protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {

// 找合适的增强器对象
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
// 若为空表示没找到
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}

findEligibleAdvisors

定位: org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findEligibleAdvisors

1
2
3
4
5
6
7
8
9
10
11
12
13
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 将当前容器中所有的切面类的切面逻辑进行封装,从而得到目标 Advisor 实例
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 对获取到的所有 Advisor 进行判断,看其切面定义是否可以应用到当前 bean,从而得到最终需要应用的 Advisor
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
// 提供的 hook 方法,用于对目标 Advisor 进行扩展
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
// 对需要代理的 Advisor 按照一定的规则进行排序
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}

extendAdvisors

定位: org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator#extendAdvisors

将 ExposeInvocationInterceptor 添加到 advice 链的开头。使用AspectJ切入点表达式时需要此附加建议,以及在使用AspectJ风格的建议时。

1
2
3
protected void extendAdvisors(List<Advisor> candidateAdvisors) {
AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(candidateAdvisors);
}

定位: org.springframework.aop.aspectj.AspectJProxyUtils#makeAdvisorChainAspectJCapableIfNecessary

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static boolean makeAdvisorChainAspectJCapableIfNecessary(List<Advisor> advisors) {
// Don't add advisors to an empty list; may indicate that proxying is just not required
if (!advisors.isEmpty()) {
boolean foundAspectJAdvice = false;
for (Advisor advisor : advisors) {
// Be careful not to get the Advice without a guard, as this might eagerly
// instantiate a non-singleton AspectJ aspect...
if (isAspectJAdvice(advisor)) {
foundAspectJAdvice = true;
break;
}
}
// 存在 AspectJAdvice, 但是不存在 ExposeInvocationInterceptor
if (foundAspectJAdvice && !advisors.contains(ExposeInvocationInterceptor.ADVISOR)) {
// 添加 advice 链开头
advisors.add(0, ExposeInvocationInterceptor.ADVISOR);
return true;
}
}
return false;
}

AopUtils#findAdvisorsThatCanApply

定位: org.springframework.aop.support.AopUtils#findAdvisorsThatCanApply

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

// 对 pointcut 表达式进行匹配
// 进行切点表达式的匹配最重要的就是 ClassFilter 和 MethodMatcher 这两个方法的实现。
// MethodMatcher 中有两个 matches 方法。一个参数是只有 Method 对象和 targetClass,另一个参数有
// Method 对象和 targetClass 对象还有一个 Method 的方法参数,他们两个的区别是:
// 两个参数的 matches 是用于静态的方法匹配 三个参数的 matches 是在运行期动态的进行方法匹配的
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
Assert.notNull(pc, "Pointcut must not be null");
// 先进行 ClassFilter 的 matches 方法校验
// 首先这个类要在所匹配的规则下
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}

// 再进行 MethodMatcher 方法级别的校验
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) {
// 只要有一个方法能匹配到就返回 true
// 这里就会有一个问题:因为在一个目标中可能会有多个方法存在,有的方法是满足这个切点的匹配规则的
// 但是也可能有一些方法是不匹配切点规则的,这里检测的是只有一个 Method 满足切点规则就返回 true
// 所以在运行时进行方法拦截的时候还会有一次运行时的方法切点规则匹配
if (introductionAwareMethodMatcher != null ?
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
// 通过方法匹配器进行匹配
methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}