Spring AOP源碼目錄
Spring AOP源碼01:Jdk動態(tài)代理底層源碼
Spring AOP源碼02:ProxyFactory
Spring AOP源碼03:JdkDynamicAopProxy
Spring AOP源碼04:MethodInvocation 攔截器調用
Spring AOP源碼05:DefaultAdvisorAutoProxyCreator
Spring期末考壓軸題:當Spring AOP遇上循環(huán)依賴
git注釋源碼地址:https://github.com/chaitou/spring-framework-master.git
前言
前面已經(jīng)學習了ProxyFactory的源碼,學習了如何手動硬編碼使用最基礎的Spring AOP,以及實現(xiàn)方式。這一節(jié)要學習自動代理DefaultAdvisorAutoProxyCreator源碼。比起Spring AOP注解形式實現(xiàn)自動代理,我們之前學習的ProxyFactory還差以下2步:
- 代理時機:在Spring Ioc創(chuàng)建Bean的過程中,尋找合適的時機進行調用Spring AOP進行代理
- 自動代理:搜索所有bean中注解了
@Aspect的類,并且提取Advisor(切面)。當一個正常的bean創(chuàng)建時,從這些候選的Advisor(切面)通過Pointcut尋找與之匹配的Advice,最后生成攔截器,再調用Proxy.getProxy()獲取代理
一、代理時機
這一點應該引起大家的注意,因為很多書以及博客都沒有講明白,都是簡單的一筆帶過,但是筆者卻認為如果連代理時機都弄不清楚,還談什么自動代理呢?
1. DefaultAdvisorAutoProxyCreator類圖
!](https://upload-images.jianshu.io/upload_images/8190955-bc261b8789f5ad01?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
之前的Spring Ioc源碼專題的生命周期中提到過這么一段話:
spring使用模板模式,在bean的創(chuàng)建過程中安插了
許多錨點,用戶尋找對應的錨點,通過重寫方法介入到bean的創(chuàng)建過程當中。
想要介入Spring Ioc創(chuàng)建Bean的過程,最好的方式就是實現(xiàn)BeanPostProcessor,想必Spring AOP也正式通過這種方式介入Bean的創(chuàng)建,實現(xiàn)自動代理的吧??梢钥吹?code>DefaultAdvisorAutoProxyCreator類圖最左邊的分支上就實現(xiàn)了SmartInstantiationAwareBeanPostProcessor,在DefaultAdvisorAutoProxyCreator的父類AbstractAutoProxyCreator中,我們找到了其實現(xiàn)的后置方法
- postProcessBeforeInitialization 初始化前擴展
- postProcessAfterInitialization 初始化后擴展
- postProcessBeforeInstantiation 對象實例化前擴展
- postProcessAfterInstantiation 對象實例化后擴展
- postProcessPropertyValues 屬性依賴注入前擴展
5個后置處理器,只有2個有具體的實現(xiàn),分別是postProcessBeforeInstantiation實例化前和postProcessAfterInitialization初始化后
2. 源碼分析
我們從Spring Ioc創(chuàng)建開始跟中,在創(chuàng)建bean
// AbstractAutowireCapableBeanFactory.java
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// 省略無關代碼...
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
/**
* 實例化前的后置處理器
* 給BeanPostProcessors一個機會返回代理替換調真實的實例,主要是來執(zhí)行實現(xiàn)了InstantiationAwareBeanPostProcessor接口的BeanPostProcessor
*
* ① 重點:
* AOP代理時機 1. 當用戶自定義TargetSource將會在實例化前進行代理,此時的TargetSource直接返回需要被代理的Bean,也就是說該被代理的Bean的實例化初始化操作均由自己負責。并進行短路操作
* 2. 用戶不自定義TargetSource時則返回空,在初始化后才進行AOP代理
*/
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
// ② 如果此時返回的bean不為空,直接短路,不再進行bean的實例化、填充、初始化!
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
// 核心邏輯
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
...
}
① 在bean實例化前的這個操作非常重要,之前我們在Spring Ioc時說,這邊一般都返回空,但是什么時候不返回空呢?帶著這個問題繼續(xù)往下看源碼
② 當不為空時,直接就return了!也就是說bean直接就不實例化、填充、初始化了!
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
// 確認bean在初始化階段之前
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
// 確認當前beanName所要返回的最終類型
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
// 只有前置處理返回的bean不為null, 才進行初始化后置處理(Aop的代理在初始化后置處理中進行)
// 但是除非bean自定義了TargetSource,否則前置處理返回的bean為空
// 一般沒有自定義TargetSource情況下,是不會在實例化前調用該后置處理,也不會導致后續(xù)短路操作!
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
// 實例化后置處理
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
前面我們提到5個后置處理器,只有2個有具體的實現(xiàn),分別是postProcessBeforeInstantiation實例化前和postProcessAfterInitialization初始化后,跟上方代碼已經(jīng)完全對上了。接下來我們就去AbstractAutoProxyCreator中看看這2個后置處理器到底做了什么工作
3. postProcessBeforeInstantiation
// AbstractAutoProxyCreator.java
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
// 省略無關代碼...
/**
* 如果我們有自定義的TargetSource,在此處創(chuàng)建代理。
* TargetSource將以自定義方式處理目標實例。
*/
// 獲取自定義TargetSource
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
// 獲取攔截器
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
// 生成代理,跟之前說過的Proxy.getProxy一樣的
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
// 實在緩存
this.proxyTypes.put(cacheKey, proxy.getClass());
// 返回代理
return proxy;
}
return null;
}
只有targetSource != null才會返回bean,也就是說只有自定義了targetSource,從而導致后續(xù)短路操作。自定義targetSource的意思就是說我們自己負責target的創(chuàng)建,不需要你Spring Ioc插手。那么targetSource到底有什么用呢?例如CommonsPoolTargetSource:可以池化TargetSource,每次執(zhí)行時從池中取代理對象,執(zhí)行完方法再返回池中,這里不扯遠
4. postProcessAfterInitialization
// AbstractAutoProxyCreator.java
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
// 緩存key,一般為beanClassName_beanName
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// bean如果有需要將會被AOP代理
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
5. 代理時機總結
- 當用戶自定義了
targetSource,說明代理目標target由用戶自己負責窗口(包括實例化等步驟),因此在bean初始化前就會調用AbstractAutoProxyCreator的postProcessBeforeInstantiation生成代理。生成后的代理已經(jīng)是完整形態(tài),因此,直接調用postProcessAfterInitialization對該代理進行完善,接著直接返回,進行短路操作!不需要再進行Spring Ioc創(chuàng)建bean的過程! - 當用戶沒自定義targetSource時,那么這個步驟返回的便是null,則會進行Spring Ioc創(chuàng)建bean的標準程序,實例化、填充屬性、初始化。并且在postProcessAfterInitialization中調用
wrapIfNecessary進行AOP代理
代理時機流程圖:
二、自動代理
上面已經(jīng)說了,代理時機分為2種,但是絕大部分情況還是使用的是第二種!也就是在初始化后進行AOP代理。上面在初始化后置處理器看到AOP通過wrapIfNecessary完成
// AbstractAutoProxyCreator.java
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 該bean已經(jīng)處理過了,則直接返回
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
// 無需被增強,也跳過
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
// 如果該bean是基礎類,或者指定了該bean不需要代理,則不進行代理,跳過
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
// 1. 獲取增強攔截器
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 存在增強,則進行代理
if (specificInterceptors != DO_NOT_PROXY) {
// 緩存表明該bean需要被增強
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 2. 創(chuàng)建代理
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
// 緩存表明bean已經(jīng)增強過
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
1. 獲取增強攔截器
// AbstractAdvisorAutoProxyCreator.java
protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
// 1. 獲取所有Advisor 2. 在所有Advisor中挑選適用的Advisor
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 獲取所有Advisor
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 在所有Advisor中尋找適用于該bean的Advisor
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
// 對所有Advisor進行排序
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
1.1 findCandidateAdvisors
// AnnotationAwareAspectJAutoProxyCreator.java
protected List<Advisor> findCandidateAdvisors() {
// Add all the Spring advisors found according to superclass rules.
// 適用注解方式配置AOP,但是可能也還存在xml配置的AOP,因此調用父類方法加載xml中的AOP聲明
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
if (this.aspectJAdvisorsBuilder != null) {
// 為所有注解了@Aspect類創(chuàng)建增強
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
// BeanFactoryAspectJAdvisorsBuilder.java
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;//- 獲取Aspect切面的beanName
// 說明還沒有緩存,需要從頭遍歷所有bean,找出注解了@Aspect的bean
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new ArrayList<>();
aspectNames = new ArrayList<>();
// 通過BeanFactory,也就是Ioc容器獲取所有的beanName
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
// 循環(huán)所有beanName
for (String beanName : beanNames) {
// 不合法的bean直接跳過,規(guī)則由子類定義
if (!isEligibleBean(beanName)) {
continue;
}
// We must be careful not to instantiate beans eagerly as in this case they
// would be cached by the Spring container but would not have been weaved.
// 獲取bean類型
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
// 該bean被Aspect注解
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);//- 緩存被Aspect注解的beanName
AspectMetadata amd = new AspectMetadata(beanType, beanName);
/**
* singleton:即切面只會有一個實例;
* perthis:每個切入點表達式匹配的連接點對應的AOP對象(代理對象)都會創(chuàng)建一個新切面實例;
* pertarget:每個切入點表達式匹配的連接點對應的目標對象都會創(chuàng)建一個新的切面實例
*/
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
// 解析增強方法
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
// 如果bean是單例,則直接緩存Advisor
this.advisorsCache.put(beanName, classAdvisors);
}
else {
// 不是單例的情況下,只能緩存工廠,每次都取增強都得新生產(chǎn)一個
this.aspectFactoryCache.put(beanName, factory);
}
// 添加Advisor
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;
}
1.2 findAdvisorsThatCanApply
// AbstractAdvisorAutoProxyCreator.java
protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
// 匹配當前bean適用的advisors,只匹配到類,只有調用時JdkDynamicAopProxy.invoke才匹配到方法
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
}
finally {
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new ArrayList<>();
//- 處理引介增強
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
}
}
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor) {
// already processed
continue;
}
//- 處理普通bean
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
if (advisor instanceof IntroductionAdvisor) {
return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
}
else if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pca = (PointcutAdvisor) advisor;
// 獲取Pointcut跟targetClass做匹配
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
}
else {
// It doesn't have a pointcut so we assume it applies.
return true;
}
}
創(chuàng)建代理流程圖:
2. 創(chuàng)建代理
創(chuàng)建代理我們已經(jīng)詳解過ProxyFactory,設置接口,設置代理目標,設置增強,最后生成代理
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);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
// 添加代理接口
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
// 設置增強
proxyFactory.addAdvisors(advisors);
// 設置代理目標類
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 創(chuàng)建代理,在之前的proxyFactory已經(jīng)詳解過
return proxyFactory.getProxy(getProxyClassLoader());
}
創(chuàng)建代理,這個接下去就很熟悉了
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}