Spring AOP源碼目錄
Spring AOP源碼01:Jdk動(dòng)態(tài)代理底層源碼
Spring AOP源碼02:ProxyFactory
Spring AOP源碼03:JdkDynamicAopProxy
Spring AOP源碼04:MethodInvocation 攔截器調(diào)用
Spring AOP源碼05:DefaultAdvisorAutoProxyCreator
Spring期末考?jí)狠S題:當(dāng)Spring AOP遇上循環(huán)依賴
git注釋源碼地址:https://github.com/chaitou/spring-framework-master.git
前言
前面已經(jīng)學(xué)習(xí)了ProxyFactory
的源碼,學(xué)習(xí)了如何手動(dòng)硬編碼使用最基礎(chǔ)的Spring AOP,以及實(shí)現(xiàn)方式为黎。這一節(jié)要學(xué)習(xí)自動(dòng)代理DefaultAdvisorAutoProxyCreator
源碼言缤。比起Spring AOP注解形式實(shí)現(xiàn)自動(dòng)代理竹握,我們之前學(xué)習(xí)的ProxyFactory
還差以下2步:
- 代理時(shí)機(jī):在Spring Ioc創(chuàng)建Bean的過(guò)程中铣耘,尋找合適的時(shí)機(jī)進(jìn)行調(diào)用Spring AOP進(jìn)行代理
- 自動(dòng)代理:搜索所有bean中注解了
@Aspect
的類票堵,并且提取Advisor
(切面)慎璧。當(dāng)一個(gè)正常的bean創(chuàng)建時(shí),從這些候選的Advisor
(切面)通過(guò)Pointcut
尋找與之匹配的Advice
哄孤,最后生成攔截器
耕驰,再調(diào)用Proxy.getProxy()
獲取代理
一、代理時(shí)機(jī)
這一點(diǎn)應(yīng)該引起大家的注意录豺,因?yàn)楹芏鄷约安┛投紱](méi)有講明白朦肘,都是簡(jiǎn)單的一筆帶過(guò),但是筆者卻認(rèn)為如果連代理時(shí)機(jī)都弄不清楚双饥,還談什么自動(dòng)代理呢媒抠?
1. DefaultAdvisorAutoProxyCreator類圖
!](https://upload-images.jianshu.io/upload_images/8190955-bc261b8789f5ad01?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
之前的Spring Ioc源碼專題的生命周期中提到過(guò)這么一段話:
spring使用模板模式,在bean的創(chuàng)建過(guò)程中安插了
許多錨點(diǎn)
咏花,用戶尋找對(duì)應(yīng)的錨點(diǎn)趴生,通過(guò)重寫方法介入到bean的創(chuàng)建過(guò)程當(dāng)中。
想要介入Spring Ioc創(chuàng)建Bean的過(guò)程昏翰,最好的方式就是實(shí)現(xiàn)BeanPostProcessor
苍匆,想必Spring AOP也正式通過(guò)這種方式介入Bean的創(chuàng)建,實(shí)現(xiàn)自動(dòng)代理的吧棚菊〗龋可以看到DefaultAdvisorAutoProxyCreator
類圖最左邊的分支上就實(shí)現(xiàn)了SmartInstantiationAwareBeanPostProcessor
,在DefaultAdvisorAutoProxyCreator
的父類AbstractAutoProxyCreator
中统求,我們找到了其實(shí)現(xiàn)的后置方法
- postProcessBeforeInitialization 初始化前擴(kuò)展
- postProcessAfterInitialization 初始化后擴(kuò)展
- postProcessBeforeInstantiation 對(duì)象實(shí)例化前擴(kuò)展
- postProcessAfterInstantiation 對(duì)象實(shí)例化后擴(kuò)展
- postProcessPropertyValues 屬性依賴注入前擴(kuò)展
5個(gè)后置處理器检碗,只有2個(gè)有具體的實(shí)現(xiàn),分別是postProcessBeforeInstantiation
實(shí)例化前和postProcessAfterInitialization
初始化后
2. 源碼分析
我們從Spring Ioc創(chuàng)建開始跟中码邻,在創(chuàng)建bean
// AbstractAutowireCapableBeanFactory.java
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// 省略無(wú)關(guān)代碼...
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
/**
* 實(shí)例化前的后置處理器
* 給BeanPostProcessors一個(gè)機(jī)會(huì)返回代理替換調(diào)真實(shí)的實(shí)例折剃,主要是來(lái)執(zhí)行實(shí)現(xiàn)了InstantiationAwareBeanPostProcessor接口的BeanPostProcessor
*
* ① 重點(diǎn):
* AOP代理時(shí)機(jī) 1. 當(dāng)用戶自定義TargetSource將會(huì)在實(shí)例化前進(jìn)行代理,此時(shí)的TargetSource直接返回需要被代理的Bean像屋,也就是說(shuō)該被代理的Bean的實(shí)例化初始化操作均由自己負(fù)責(zé)怕犁。并進(jìn)行短路操作
* 2. 用戶不自定義TargetSource時(shí)則返回空,在初始化后才進(jìn)行AOP代理
*/
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
// ② 如果此時(shí)返回的bean不為空,直接短路奏甫,不再進(jìn)行bean的實(shí)例化戈轿、填充、初始化扶檐!
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實(shí)例化前的這個(gè)操作非常重要凶杖,之前我們?cè)赟pring Ioc時(shí)說(shuō)胁艰,這邊一般都返回空款筑,但是什么時(shí)候不返回空呢?帶著這個(gè)問(wèn)題繼續(xù)往下看源碼
② 當(dāng)不為空時(shí)腾么,直接就return了奈梳!也就是說(shuō)bean直接就不實(shí)例化、填充解虱、初始化了攘须!
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
// 確認(rèn)bean在初始化階段之前
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
// 確認(rèn)當(dāng)前beanName所要返回的最終類型
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
// 只有前置處理返回的bean不為null, 才進(jìn)行初始化后置處理(Aop的代理在初始化后置處理中進(jìn)行)
// 但是除非bean自定義了TargetSource,否則前置處理返回的bean為空
// 一般沒(méi)有自定義TargetSource情況下殴泰,是不會(huì)在實(shí)例化前調(diào)用該后置處理于宙,也不會(huì)導(dǎo)致后續(xù)短路操作!
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
// 實(shí)例化后置處理
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
前面我們提到5個(gè)后置處理器悍汛,只有2個(gè)有具體的實(shí)現(xiàn)捞魁,分別是postProcessBeforeInstantiation
實(shí)例化前和postProcessAfterInitialization
初始化后,跟上方代碼已經(jīng)完全對(duì)上了离咐。接下來(lái)我們就去AbstractAutoProxyCreator
中看看這2個(gè)后置處理器到底做了什么工作
3. postProcessBeforeInstantiation
// AbstractAutoProxyCreator.java
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
// 省略無(wú)關(guān)代碼...
/**
* 如果我們有自定義的TargetSource谱俭,在此處創(chuàng)建代理。
* TargetSource將以自定義方式處理目標(biāo)實(shí)例宵蛀。
*/
// 獲取自定義TargetSource
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
// 獲取攔截器
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
// 生成代理昆著,跟之前說(shuō)過(guò)的Proxy.getProxy一樣的
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
// 實(shí)在緩存
this.proxyTypes.put(cacheKey, proxy.getClass());
// 返回代理
return proxy;
}
return null;
}
只有targetSource != null
才會(huì)返回bean,也就是說(shuō)只有自定義了targetSource
术陶,從而導(dǎo)致后續(xù)短路操作凑懂。自定義targetSource
的意思就是說(shuō)我們自己負(fù)責(zé)target
的創(chuàng)建,不需要你Spring Ioc插手梧宫。那么targetSource
到底有什么用呢征候?例如CommonsPoolTargetSource
:可以池化TargetSource
,每次執(zhí)行時(shí)從池中取代理對(duì)象祟敛,執(zhí)行完方法再返回池中疤坝,這里不扯遠(yuǎn)
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如果有需要將會(huì)被AOP代理
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
5. 代理時(shí)機(jī)總結(jié)
- 當(dāng)用戶自定義了
targetSource
馆铁,說(shuō)明代理目標(biāo)target
由用戶自己負(fù)責(zé)窗口(包括實(shí)例化等步驟)跑揉,因此在bean初始化前就會(huì)調(diào)用AbstractAutoProxyCreator
的postProcessBeforeInstantiation
生成代理。生成后的代理已經(jīng)是完整形態(tài),因此历谍,直接調(diào)用postProcessAfterInitialization
對(duì)該代理進(jìn)行完善现拒,接著直接返回,進(jìn)行短路操作望侈!不需要再進(jìn)行Spring Ioc創(chuàng)建bean的過(guò)程印蔬! - 當(dāng)用戶沒(méi)自定義targetSource時(shí),那么這個(gè)步驟返回的便是null脱衙,則會(huì)進(jìn)行Spring Ioc創(chuàng)建bean的標(biāo)準(zhǔn)程序侥猬,實(shí)例化、填充屬性捐韩、初始化退唠。并且在postProcessAfterInitialization中調(diào)用
wrapIfNecessary
進(jìn)行AOP代理
代理時(shí)機(jī)流程圖:
二、自動(dòng)代理
上面已經(jīng)說(shuō)了荤胁,代理時(shí)機(jī)分為2種瞧预,但是絕大部分情況還是使用的是第二種!也就是在初始化后進(jìn)行AOP代理仅政。上面在初始化后置處理器看到AOP通過(guò)wrapIfNecessary
完成
// AbstractAutoProxyCreator.java
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 該bean已經(jīng)處理過(guò)了垢油,則直接返回
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
// 無(wú)需被增強(qiáng),也跳過(guò)
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
// 如果該bean是基礎(chǔ)類圆丹,或者指定了該bean不需要代理滩愁,則不進(jìn)行代理,跳過(guò)
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
// 1. 獲取增強(qiáng)攔截器
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 存在增強(qiáng)运褪,則進(jìn)行代理
if (specificInterceptors != DO_NOT_PROXY) {
// 緩存表明該bean需要被增強(qiáng)
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)增強(qiáng)過(guò)
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
1. 獲取增強(qiáng)攔截器
// 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()) {
// 對(duì)所有Advisor進(jìn)行排序
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,因此調(diào)用父類方法加載xml中的AOP聲明
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
if (this.aspectJAdvisorsBuilder != null) {
// 為所有注解了@Aspect類創(chuàng)建增強(qiáng)
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
// BeanFactoryAspectJAdvisorsBuilder.java
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;//- 獲取Aspect切面的beanName
// 說(shuō)明還沒(méi)有緩存秸讹,需要從頭遍歷所有bean檀咙,找出注解了@Aspect的bean
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new ArrayList<>();
aspectNames = new ArrayList<>();
// 通過(guò)BeanFactory,也就是Ioc容器獲取所有的beanName
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
// 循環(huán)所有beanName
for (String beanName : beanNames) {
// 不合法的bean直接跳過(guò)璃诀,規(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:即切面只會(huì)有一個(gè)實(shí)例弧可;
* perthis:每個(gè)切入點(diǎn)表達(dá)式匹配的連接點(diǎn)對(duì)應(yīng)的AOP對(duì)象(代理對(duì)象)都會(huì)創(chuàng)建一個(gè)新切面實(shí)例;
* pertarget:每個(gè)切入點(diǎn)表達(dá)式匹配的連接點(diǎn)對(duì)應(yīng)的目標(biāo)對(duì)象都會(huì)創(chuàng)建一個(gè)新的切面實(shí)例
*/
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
// 解析增強(qiáng)方法
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
// 如果bean是單例劣欢,則直接緩存Advisor
this.advisorsCache.put(beanName, classAdvisors);
}
else {
// 不是單例的情況下棕诵,只能緩存工廠,每次都取增強(qiáng)都得新生產(chǎn)一個(gè)
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) {
// 從緩存中獲取增強(qiáng)
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 {
// 匹配當(dāng)前bean適用的advisors凿将,只匹配到類校套,只有調(diào)用時(shí)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<>();
//- 處理引介增強(qiáng)
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)詳解過(guò)ProxyFactory,設(shè)置接口牧抵,設(shè)置代理目標(biāo)笛匙,設(shè)置增強(qiáng)侨把,最后生成代理
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();
// 獲取當(dāng)前類的相關(guān)屬性
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
// 添加代理接口
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
// 設(shè)置增強(qiáng)
proxyFactory.addAdvisors(advisors);
// 設(shè)置代理目標(biāo)類
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// 創(chuàng)建代理,在之前的proxyFactory已經(jīng)詳解過(guò)
return proxyFactory.getProxy(getProxyClassLoader());
}
創(chuàng)建代理妹孙,這個(gè)接下去就很熟悉了
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}