通過(guò)上節(jié)我們了解了AnnotationAwareAspectJAutoProxyCreator的其中之一的作用霜浴,是作為一個(gè)后置處理器在我們創(chuàng)建單實(shí)例bean之前攔截嘗試著先去創(chuàng)建代理對(duì)象,如果是找到了直接返回瘪板,當(dāng)然它作為此類(lèi)型的【InstantiationAwareBeanPostProcessor】的后置處理器跟我們之前的BeanPostProcessor【后置處理器】是有區(qū)別的:
區(qū)別
兩者最大的區(qū)別在于創(chuàng)建bean的執(zhí)行的時(shí)機(jī)不同
- BeanPostProcessor:是在我們初始化bean的前后進(jìn)行相關(guān)的操作
- InstantiationAwareBeanPostProcessor:是在我們bean的創(chuàng)建之前進(jìn)行攔截烛卧,然后自己嘗試著去創(chuàng)建代理對(duì)象,如果存在直接使用此代理對(duì)象
所以說(shuō),spring中的每一種類(lèi)型的BeanPostProcessor都有自己的執(zhí)行時(shí)機(jī)绞佩,這也是對(duì)于我們是一個(gè)難點(diǎn),接著我們來(lái)說(shuō)AnnotationAwareAspectJAutoProxyCreator的另外一個(gè)作用猪钮,首先我們?cè)賮?lái)復(fù)習(xí)一下它的類(lèi)圖:
通過(guò)它的繼承和實(shí)現(xiàn)關(guān)系品山,我們還會(huì)發(fā)現(xiàn)AnnotationAwareAspectJAutoProxyCreator的父類(lèi)AbstractAutoProxyCreator實(shí)現(xiàn)了BeanFactoryAware此接口,那么必然會(huì)實(shí)現(xiàn)該接口的#setBeanFactory(...)方法
- 在我們的頂級(jí)父類(lèi)AbstractAutoProxyCreator中有這樣的一段代碼:
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
- 同樣不難猜測(cè)在它的子類(lèi)AbstractAdvisorAutoProxyCreator中:
@Override
public void setBeanFactory(BeanFactory beanFactory) {
super.setBeanFactory(beanFactory);
if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
throw new IllegalArgumentException(
"AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
}
initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
}
發(fā)現(xiàn)子類(lèi)重寫(xiě)了setBeanFactory(....)方法烤低,說(shuō)了這么多肘交,我們其主要關(guān)注的核心還需要放在頂級(jí)分類(lèi)AbstractAutoProxyCreator中來(lái)完成接下來(lái)的分析,現(xiàn)在我們要把關(guān)注的核心點(diǎn)來(lái)放在我們自己編寫(xiě)的業(yè)務(wù)類(lèi)和日志切面類(lèi)的創(chuàng)建
AbstractAutoProxyCreator
在這個(gè)類(lèi)中扑馁,它既扮演了postProcessor的角色也扮演了BeanFactoryAware的角色涯呻,至于BeanFactoryAware角色來(lái)講我們已經(jīng)知道它重寫(xiě)了setBeanFactory(...)方法,不必多說(shuō)檐蚜,我們?cè)贏bstractAutoProxyCreator類(lèi)中會(huì)發(fā)現(xiàn)#postProcessBeforeInstantiation(...)和#postProcessAfterInstantiation(...)這兩個(gè)方法值得我們注意下魄懂,我們給他打上斷點(diǎn),首先分析的入口還是我們的測(cè)試類(lèi):
//Aop測(cè)試
@Test
public void testAop(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAop.class);
MathCalculator calculator = applicationContext.getBean(MathCalculator.class);
calculator.div(10,5);
applicationContext.close();
}
跟蹤代碼我們來(lái)到AbstractApplicatContext#refresh()方法闯第,我們一步一步Dbug當(dāng)來(lái)到this.registerBeanPostProcessors(beanFactory)此處是市栗,斷點(diǎn)進(jìn)入我們的AbstractAutoProxyCreator#setBeanFactory(...)方法,直接跳過(guò)來(lái)到refresh()方法咳短,接著當(dāng)斷點(diǎn)來(lái)到this.finishBeanFactoryInitialization(beanFactory)時(shí)跳到AbstractAutoProxyCreator#postProcessBeforeInstantiation(....)方法上填帽,那么我們?cè)诖藭r(shí)進(jìn)行分析,當(dāng)然這里只關(guān)心我們自己寫(xiě)的bean的創(chuàng)建具體如下圖:
當(dāng)我們執(zhí)行完postProcessBeforeInstantiation方法之后會(huì)執(zhí)行postProcessAfterInstantiation方法咙好,兩個(gè)方法交替執(zhí)行篡腌,多提了一點(diǎn),回歸正題:
- 首先獲取當(dāng)前的bean的名字
Object cacheKey = getCacheKey(beanClass, beanName);
- 通過(guò)如下的方式來(lái)判斷當(dāng)前bean是否在advisedBeans中存在
private final Map<Object, Boolean> advisedBeans = new ConcurrentHashMap<>(256);
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
其中advisedBeans 保存了所有需要增強(qiáng)的bean勾效,因?yàn)榇丝涛覀兊男枰鰪?qiáng)的業(yè)務(wù)類(lèi)添加進(jìn)此緩存中嘹悼,所以直接跳過(guò)此判斷來(lái)到:
- 通過(guò)如下的判斷當(dāng)前bean是否是一個(gè)基礎(chǔ)類(lèi)型的bean
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
通過(guò)方法#isInfrastructureClass(beanClass)來(lái)判斷是否是一個(gè)基礎(chǔ)類(lèi)型的叛甫,那什么是基礎(chǔ)類(lèi)型的bean,跟蹤代碼來(lái)到:
protected boolean isInfrastructureClass(Class<?> beanClass) {
return super.isInfrastructureClass(beanClass) || this.aspectJAdvisorFactory != null && this.aspectJAdvisorFactory.isAspect(beanClass);
}
這里我們看到的是調(diào)用了父類(lèi)的super.isInfrastructureClass(beanClass)繼續(xù)跟蹤代碼來(lái)到:
protected boolean isInfrastructureClass(Class<?> beanClass) {
boolean retVal = Advice.class.isAssignableFrom(beanClass) || Pointcut.class.isAssignableFrom(beanClass) || Advisor.class.isAssignableFrom(beanClass) || AopInfrastructureBean.class.isAssignableFrom(beanClass);
if (retVal && this.logger.isTraceEnabled()) {
this.logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
}
return retVal;
}
這里就明確了杨伙,原來(lái)基礎(chǔ)類(lèi)型是Advice其监、Pointcut、Advisor限匣、AopInfrastructureBean這些類(lèi)型抖苦,我們的邏輯類(lèi)肯定不是這些基礎(chǔ)類(lèi)型,直接放行來(lái)到上層米死,其中我們注意一點(diǎn):this.aspectJAdvisorFactory.isAspect(beanClass)是這個(gè)類(lèi)型的锌历,繼續(xù)跟蹤代碼來(lái)到:
public boolean isAspect(Class<?> clazz) {
return this.hasAspectAnnotation(clazz) && !this.compiledByAjc(clazz);
}
接著繼續(xù)跟蹤代碼來(lái)到:
private boolean hasAspectAnnotation(Class<?> clazz) {
return AnnotationUtils.findAnnotation(clazz, Aspect.class) != null;
}
從這里看到,我們的基礎(chǔ)類(lèi)型還包括注解@Aspect,接著來(lái)到我們的方法#postProcessBeforeInstantiation()開(kāi)始位置
同時(shí)通過(guò)this.shouldSkip(beanClass, beanName)來(lái)判斷是否需要跳過(guò)
通過(guò)下面代碼來(lái)判斷是否需要在此處創(chuàng)建代理
TargetSource targetSource = this.getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
在這里創(chuàng)建代理對(duì)象的前提時(shí)我們已經(jīng)自定義代理的目標(biāo)對(duì)象峦筒,很顯然我們是沒(méi)有的究西,直接跳過(guò)來(lái)到#postProcessAfterInitialization(....)方法:
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return this.wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
其中方法this.wrapIfNecessary(bean, beanName, cacheKey)需要我們注意下,意思是如果需要包裝的情況下會(huì)調(diào)用此方法勘天,我們繼續(xù)跟蹤代碼:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
} else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
} else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
} else {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
} else {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
}
簡(jiǎn)單的分析下上述代碼的過(guò)程:
- 通過(guò)!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)來(lái)判斷當(dāng)前bean是否是基礎(chǔ)類(lèi)型的和是否需要跳過(guò)
- 通過(guò)如下代碼來(lái)獲取當(dāng)前bean的所有增強(qiáng)器(也就是通知方法)specificInterceptors
getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource)
跟蹤代碼來(lái)到此方法:
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
List<Advisor> advisors = this.findEligibleAdvisors(beanClass, beanName);
return advisors.isEmpty() ? DO_NOT_PROXY : advisors.toArray();
}
發(fā)現(xiàn)通過(guò)繼續(xù)調(diào)用內(nèi)部的方法#this.findEligibleAdvisors(beanClass, beanName);其中參數(shù)為上圖中紅色框內(nèi)的怔揩,繼續(xù)跟蹤代碼來(lái)到:
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
List<Advisor> candidateAdvisors = this.findCandidateAdvisors();
List<Advisor> eligibleAdvisors = this.findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
this.extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = this.sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
-
首先一進(jìn)方法將獲取到的后補(bǔ)增強(qiáng)器存放咋list中【candidateAdvisors 】
image.png 接著是通過(guò)如下的代碼是獲取能作用于我們當(dāng)前bean的增強(qiáng)器
List<Advisor> eligibleAdvisors = this.findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
我們來(lái)看看#findAdvisorsThatCanApply(...)是如何查找的過(guò)程
protected List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
List var4;
try {
var4 = AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
} finally {
ProxyCreationContext.setCurrentProxiedBeanName((String)null);
}
return var4;
}
首先一進(jìn)方法將當(dāng)前 要增強(qiáng)的bean進(jìn)行了設(shè)置
接著通過(guò)Aop的工具去查找,最后進(jìn)行返回
接著通過(guò)如下方法對(duì)我們的增強(qiáng)器進(jìn)行排序操作
this.sortAdvisors(eligibleAdvisors);
下圖所示的最終排序之后的增強(qiáng)器
其實(shí)就是我們自己編寫(xiě)的切面那些方法脯丝,繼續(xù)跟蹤代碼:
- 將當(dāng)前需要增強(qiáng)的bean添加到advisedBeans 中商膊,通過(guò)下面代碼:
this.advisedBeans.put(cacheKey, Boolean.TRUE);
- 如果當(dāng)前bean需要增強(qiáng)的話,就為它進(jìn)行代理對(duì)象的創(chuàng)建
Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
繼續(xù)跟蹤代碼來(lái)到AbstractAutoProxyCreator類(lèi)中的#createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource)方法宠进,我們來(lái)看看具體代碼創(chuàng)建邏輯過(guò)程:
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (this.shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
} else {
this.evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
圖中是上述的方法中用到的參數(shù)類(lèi)型晕拆,需要我們來(lái)注意的一點(diǎn)是 this.evaluateProxyInterfaces(beanClass, proxyFactory)此方法,此方法主要的目的是將當(dāng)前bean的類(lèi)型設(shè)置為一個(gè)ProxyFactory
- 通過(guò)如下代碼來(lái)獲取當(dāng)前bean所有的通知方法(增強(qiáng)器)
Advisor[] advisors = this.buildAdvisors(beanName, specificInterceptors);
- 接著是保存到proxyFactory中
proxyFactory.addAdvisors(advisors);
- 接著通過(guò)如下的代碼進(jìn)行代理對(duì)象的真正創(chuàng)建過(guò)程:
proxyFactory.getProxy(this.getProxyClassLoader());
跟蹤代碼來(lái)到:
public Object getProxy(@Nullable ClassLoader classLoader) {
return this.createAopProxy().getProxy(classLoader);
}
繼續(xù)看我們的createAopProxy()方法
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
return new JdkDynamicAopProxy(config);
} else {
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.");
} else {
return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
}
}
}
通過(guò)上面的代碼spring自動(dòng)幫我們創(chuàng)建了ObjenesisCglibAopProxy 類(lèi)型的CGLIB代理材蹬,最后一路返回來(lái)到我們AbstractAutoProxyCreator類(lèi)中的#wrapIfNecessary()方法
- 通過(guò)如下操作將當(dāng)前要增強(qiáng)的組件代理對(duì)象的class類(lèi)型返回給容器中
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
這樣做的目的是我們下節(jié)要說(shuō)的实幕,通過(guò)創(chuàng)建的代理對(duì)象來(lái)執(zhí)行我們的目標(biāo)方法,那么關(guān)于AOP代理對(duì)象的創(chuàng)建分析就到這了....