Spring AOP源碼解析

1、AOP核心概念

1)疤祭、橫切關(guān)注點(diǎn)(對(duì)哪些方法進(jìn)行切入)

對(duì)哪些方法進(jìn)行攔截,攔截后怎么處理饵婆,這些關(guān)注點(diǎn)稱(chēng)之為橫切關(guān)注點(diǎn)

2)勺馆、切面(aspect,把原來(lái)糅雜在業(yè)務(wù)邏輯代碼中的非業(yè)務(wù)代碼抽取出來(lái),把功能相同的放在一個(gè)類(lèi)中形成一個(gè)切面)

類(lèi)是對(duì)物體特征的抽象侨核,切面就是對(duì)橫切關(guān)注點(diǎn)的抽象

3)草穆、連接點(diǎn)(joinpoint)(需要切入的點(diǎn))

被攔截到的點(diǎn),因?yàn)镾pring只支持方法類(lèi)型的連接點(diǎn)搓译,所以在Spring中連接點(diǎn)指的就是被攔截到的方法悲柱,實(shí)際上連接點(diǎn)還可以是字段或者構(gòu)造器

4)、切入點(diǎn)(pointcut)

對(duì)連接點(diǎn)進(jìn)行攔截的定義

5)些己、通知(advice)

所謂通知指的就是指攔截到連接點(diǎn)之后要執(zhí)行的代碼豌鸡,通知分為前置、后置段标、異常涯冠、最終、環(huán)繞通知五類(lèi)

6)怀樟、目標(biāo)對(duì)象

代理的目標(biāo)對(duì)象

7)功偿、織入(weave)

將切面應(yīng)用到目標(biāo)對(duì)象并導(dǎo)致代理對(duì)象創(chuàng)建的過(guò)程

8)、引入(introduction)

在不修改代碼的前提下,引入可以在運(yùn)行期為類(lèi)動(dòng)態(tài)地添加一些方法或字段

簡(jiǎn)單案例:

public interface Calculate {

/**

* 加法

* @param numA

* @param numB

* @return

*/

int add(int numA,int numB);

/**

* 減法

* @param numA

* @param numB

* @return

*/

int reduce(int numA,int numB);

/**

* 除法

* @param numA

* @param numB

* @return

*/

int div(int numA,int numB);

/**

* 乘法

* @param numA

* @param numB

* @return

*/

int multi(int numA,int numB);

}

=====================實(shí)現(xiàn)類(lèi)

public class CalculateImpl implements Calculate {

public int add(int numA, int numB) {

return numA+numB;

}

public int reduce(int numA, int numB) {

return numA-numB;

}

public int div(int numA, int numB) {

return numA/numB;

}

public int multi(int numA, int numB) {

return numA*numB;

}

}

=====================切面類(lèi)=====================

@Aspect

public class LogAspect {

@Pointcut("execution(* com.jd.CalculateImpl.*(..))")

public void pointCut(){};

@Before(value = "pointCut()")

public void methodBefore(JoinPoint joinPoint){

String methodName = joinPoint.getSignature().getName();

System.out.println("執(zhí)行目標(biāo)方法【"+methodName+"】之前執(zhí)行<前置通知>,入?yún)?+ Arrays.asList(joinPoint.getArgs()));

}

@After(value = "pointCut()")

public void methodAfter(JoinPoint joinPoint) {

String methodName = joinPoint.getSignature().getName();

System.out.println("執(zhí)行目標(biāo)方法【"+methodName+"】之前執(zhí)行<后置通知>,入?yún)?+Arrays.asList(joinPoint.getArgs()));

}

@AfterReturning(value = "pointCut()")

public void methodReturning(JoinPoint joinPoint ) {

String methodName = joinPoint.getSignature().getName();

System.out.println("執(zhí)行目標(biāo)方法【"+methodName+"】之前執(zhí)行<返回通知>,入?yún)?+Arrays.asList(joinPoint.getArgs()));

}

@AfterThrowing(value = "pointCut()")

public void methodAfterThrowing(JoinPoint joinPoint) {

String methodName = joinPoint.getSignature().getName();

System.out.println("執(zhí)行目標(biāo)方法【"+methodName+"】之前執(zhí)行<異常通知>,入?yún)?+Arrays.asList(joinPoint.getArgs()));

}

}

===========================配置類(lèi)=============

@Configuration

@EnableAspectJAutoProxy

public class MainConfig {

@Bean

public Calculate calculate() {

return new CalculateImpl();

}

@Bean

public LogAspect logAspect() {

return new LogAspect();

}

}


2)我們看到在我們配置類(lèi)上加入了@EnableAspectJAutoProxy這個(gè)東東械荷?我registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);

們著重來(lái)分析一下這個(gè)東東給我容器中添加了什么組件共耍?

2.1)我們發(fā)現(xiàn)@EnableAspectJAutoProxy上標(biāo)注了一個(gè)@Import注解,通過(guò)前面的學(xué)習(xí)我們知道

@Import可以給我們?nèi)萜髦刑砑咏M件

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Import(AspectJAutoProxyRegistrar.class)

public @interface EnableAspectJAutoProxy {

2.2)所有我們來(lái)分析AspectJAutoProxyRegistrar類(lèi)是用來(lái)干什么的吨瞎?

經(jīng)過(guò)跟蹤源代碼我們發(fā)現(xiàn),AspectJAutoProxyRegistrar實(shí)現(xiàn)了ImportBeanDefinitionRegistrar接口痹兜,我們以前學(xué)習(xí)過(guò)

凡是實(shí)現(xiàn)了ImportBeanDefinitionRegistrar可以給我們?nèi)萜髦刑砑觔ean定義信息

作用:往容器中注冊(cè)了一個(gè)名稱(chēng)叫org.springframework.aop.config.internalAutoProxyCreator

類(lèi)型為AnnotationAwareAspectJAutoProxyCreator 注解的apsectj自動(dòng)代理創(chuàng)建器

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

@Override

public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

//往容器中注冊(cè)對(duì)應(yīng)的 aspectj注解自動(dòng)代理創(chuàng)建器

AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

AnnotationAttributes enableAspectJAutoProxy =

AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);

if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {

AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);

}

if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {

AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);

}

}

}

======================AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);=====

public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {

? ? ?return?registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);

}

//注冊(cè)一個(gè)AnnotationAwareAspectJAutoProxyCreator(注解適配的切面自動(dòng)創(chuàng)建器)

public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);

}

private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) Assert.notNull(registry, "BeanDefinitionRegistry must not be null");

//判斷容器中有沒(méi)有org.springframework.aop.config.internalAutoProxyCreator 名稱(chēng)的bean定義

if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {

BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);

if (!cls.getName().equals(apcDefinition.getBeanClassName())) {

int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());

int requiredPriority = findPriorityForClass(cls);

if (currentPriority < requiredPriority) {

apcDefinition.setBeanClassName(cls.getName());

}

}

return null;

}

//容器中沒(méi)有 那么就注冊(cè)一個(gè)名稱(chēng)叫org.springframework.aop.config.internalAutoProxyCreator 類(lèi)型是AnnotationAwareAspectJAutoProxyCreatorRootBeanDefinition beanDefinition = new RootBeanDefinition(cls);

beanDefinition.setSource(source);

beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);

beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);

registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);

return beanDefinition;

}

3)所以我們現(xiàn)在可以分析一下AnnotationAwareAspectJAutoProxyCreator 他是什么一個(gè)鬼?

根據(jù)上訴類(lèi)圖

1)我們發(fā)現(xiàn)了AnnotationAwareAspectJAutoProxyCreator 有實(shí)現(xiàn)了***Aware接口的特性

(BeanFactoryAware)

2)還發(fā)現(xiàn)了AnnotationAwareAspectJAutoProxyCreator 實(shí)現(xiàn)了BeanPostProcessor接口(后置處理器的特性)

3)還發(fā)現(xiàn)了AnnotationAwareAspectJAutoProxyCreator 實(shí)現(xiàn)了InstantiationAwareBeanPostProcessor接口(后置

處理器的一種,在實(shí)例化之前進(jìn)行調(diào)用)

3)我們根據(jù)上AnnotationAwareAspectJAutoProxyCreator 的類(lèi)的繼承圖來(lái)分析

AnnotationAwareAspectJAutoProxyCreator 的功能

3.1)所以我們首先來(lái)分析AnnotationAwareAspectJAutoProxyCreator 實(shí)現(xiàn)了BeanFactoryAware接口 做了什么工

作?

①:org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator 實(shí)現(xiàn)了BeanFactoryAware

我們查看源碼的時(shí)候發(fā)現(xiàn)AbstractAutoProxyCreator 的setBeanFactory()方法啥都沒(méi)有做颤诀,但是又被子類(lèi)覆蓋了

@Override

public void setBeanFactory(BeanFactory beanFactory) {

this.beanFactory = beanFactory;

}

②:AbstractAdvisorAutoProxyCreator覆蓋了AbstractAutoProxyCreator.setBeanFactory()方法

做了二件事情

1:調(diào)用父類(lèi)的super.setBeanFactory(beanFactory);

2:調(diào)用本來(lái)的initBeanFactory((ConfigurableListableBeanFactory) beanFactory);初始化bean工廠

方法

但是本類(lèi)的AbstractAdvisorAutoProxyCreator.initBeanFactory()又被子類(lèi)覆蓋了

public void setBeanFactory(BeanFactory beanFactory) {

//調(diào)用父類(lèi)AbstractAutoProxyCreator.setBeanFactory()方法

super.setBeanFactory(beanFactory);

if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {

throw new IllegalArgumentException(

"AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);

}

//初始化bean工程

initBeanFactory((ConfigurableListableBeanFactory) beanFactory);

}

protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {

this.advisorRetrievalHelper = new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);

}

③:AnnotationAwareAspectJAutoProxyCreator#initBeanFactory覆蓋了

AbstractAdvisorAutoProxyCreator.initBeanFactory()方法

//創(chuàng)建一個(gè)aop的增強(qiáng)器通過(guò)@Apsectj注解的方式.

protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {

//調(diào)用父類(lèi)的

super.initBeanFactory(beanFactory);

//若 apsectj的增強(qiáng)器工廠對(duì)象為空,我們就創(chuàng)建一個(gè)ReflectiveAspectJAdvisorFactory

if (this.aspectJAdvisorFactory == null) {

this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);

}

//不為空 我們就把a(bǔ)spectJAdvisorFactory 包裝為BeanFactoryAspectJAdvisorsBuilderAdapter

this.aspectJAdvisorsBuilder =

new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);

}

總結(jié):AnnotationAwareAspectJAutoProxyCreator 實(shí)現(xiàn)了BeanFactoryAware 也是做了二個(gè)事情

事情1:把Beanfactory 保存到AnnotationAwareAspectJAutoProxyCreator 組件上.

事情2: 為AnnotationAwareAspectJAutoProxyCreator 的aspectJAdvisorsBuilder aspect增強(qiáng)器構(gòu)建器賦值

3.2)還發(fā)現(xiàn)了AnnotationAwareAspectJAutoProxyCreator 實(shí)現(xiàn)了BeanPostProcessor接口(后置處

理器的特性)

我們追根溯源 AbstractAutoProxyCreator類(lèi)實(shí)現(xiàn)了BeanPostProcessor接口 所以我們分析

BeanPostProcessor的二個(gè)方法

①:postProcessBeforeInitialization初始化之前的方法 貌似什么都沒(méi)有干

①:postProcessBeforeInitialization初始化之前的方法 貌似什么都沒(méi)有干

public Object postProcessBeforeInitialization(Object bean, String beanName) {

return bean;

}

②:postProcessAfterInitialization 這個(gè)方法很重要 很重要 很重要 很重要很重要 很重要很重要 很重要很重要 很重

要 后面單獨(dú)說(shuō)(創(chuàng)建代理對(duì)象的邏輯)

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

if (bean != null) {

Object cacheKey = getCacheKey(bean.getClass(), beanName);

if (!this.earlyProxyReferences.contains(cacheKey)) {

//包裝bean 真正的創(chuàng)建代理對(duì)象邏輯

return wrapIfNecessary(bean, beanName, cacheKey);

}

}

return bean;

}

3.3)還發(fā)現(xiàn)了AnnotationAwareAspectJAutoProxyCreator 實(shí)現(xiàn)了InstantiationAwareBeanPostProcessor接口(后

置處理器的一種,在實(shí)例化之前進(jìn)行調(diào)用)

我們追根溯源 AbstractAutoProxyCreator類(lèi)實(shí)現(xiàn)了SmartInstantiationAwareBeanPostProcessor

接口 所以我們分析SmartInstantiationAwareBeanPostProcessor的二個(gè)方法

①postProcessBeforeInstantiation方法

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {

Object cacheKey = getCacheKey(beanClass, beanName);

// 判斷TargetSource緩存中是否包含當(dāng)前bean字旭,如果不包含,則判斷當(dāng)前bean是否是已經(jīng)被代理的bean崖叫,

// 如果代理過(guò)遗淳,則不對(duì)當(dāng)前傳入的bean進(jìn)行處理,如果沒(méi)代理過(guò)心傀,則判斷當(dāng)前bean是否為系統(tǒng)bean屈暗,或者是

// 切面邏輯不會(huì)包含的bean,如果是脂男,則將當(dāng)前bean緩存到advisedBeans中养叛,否則繼續(xù)往下執(zhí)行。

// 經(jīng)過(guò)這一步的處理之后宰翅,只有在TargetSource中沒(méi)有進(jìn)行緩存弃甥,并且應(yīng)該被切面邏輯環(huán)繞,但是目前還未

// 生成代理對(duì)象的bean才會(huì)通過(guò)此方法汁讼。

if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {

if (this.advisedBeans.containsKey(cacheKey)) {

return null;

}

//若是基礎(chǔ)的class ||或者是否應(yīng)該跳過(guò) shouldSkip直接返回false

if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {

//把cacheKey 存放在advisedBeans中

this.advisedBeans.put(cacheKey, Boolean.FALSE);

//返回null

return null;

}

}

// 獲取封裝當(dāng)前bean的TargetSource對(duì)象淆攻,如果不存在,則直接退出當(dāng)前方法掉缺,否則從TargetSource

// 中獲取當(dāng)前bean對(duì)象卜录,并且判斷是否需要將切面邏輯應(yīng)用在當(dāng)前bean上。

if (beanName != null) {

TargetSource targetSource = getCustomTargetSource(beanClass, beanName);

if (targetSource != null) {

this.targetSourcedBeans.add(beanName);

//// 獲取能夠應(yīng)用當(dāng)前bean的切面邏輯

Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);

//// 根據(jù)切面邏輯為當(dāng)前bean生成代理對(duì)象

Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);

this.proxyTypes.put(cacheKey, proxy.getClass());

return proxy;

}

}

return null;

}

=============================判斷是不是基礎(chǔ)的bean=======================================

protected boolean isInfrastructureClass(Class<?> beanClass) {

//是不是Advice PointCut Advisor AopInfrastructureBean 滿(mǎn)足任意返回ture

boolean retVal = Advice.class.isAssignableFrom(beanClass) ||

Pointcut.class.isAssignableFrom(beanClass) ||

Advisor.class.isAssignableFrom(beanClass) ||

AopInfrastructureBean.class.isAssignableFrom(beanClass);

if (retVal && logger.isTraceEnabled()) {

logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");

}

return retVal;

}

②:postProcessAfterInstantiation方法

@Override

public boolean postProcessAfterInstantiation(Object bean, String beanName) {

return true;

}

4)真正的創(chuàng)建代理對(duì)象從BeanPostProcessor處理器的后置方法開(kāi)始

1:>org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization

2:>org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary 有必要的

話進(jìn)行包裝

3:>org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean

4:>org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findEligibleAdvisors

5:>org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findAdvisorsThatCanApply

6:>org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy創(chuàng)建代理對(duì)象

4.1)

1:>org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization

源碼分析

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

if (bean != null) {

//通過(guò)傳入的class 和beanName生成緩存key

Object cacheKey = getCacheKey(bean.getClass(), beanName);

if (!this.earlyProxyReferences.contains(cacheKey)) {

//若當(dāng)前bean合適被包裝為代理bean就進(jìn)行處理

return wrapIfNecessary(bean, beanName, cacheKey);

}

}

return bean;

}

4.2)2:>org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary源碼分

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {

//已經(jīng)被處理過(guò)的 不進(jìn)行下面的處理

if (beanName != null && this.targetSourcedBeans.contains(beanName)) {

return bean;

}

//不需要被增強(qiáng)的直接返回

if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {

return bean;

}

//判斷當(dāng)前bean是不是基礎(chǔ)類(lèi)型的bean,或者指定類(lèi)型的bean 不需要代理

if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {

this.advisedBeans.put(cacheKey, Boolean.FALSE);

return bean;

}

//獲取通知或者增強(qiáng)器

Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);

//獲取的不為空眶明,生成代理對(duì)象

if (specificInterceptors != DO_NOT_PROXY) {

this.advisedBeans.put(cacheKey, Boolean.TRUE);

//創(chuàng)建代理對(duì)象

Object proxy = createProxy(

bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));

this.proxyTypes.put(cacheKey, proxy.getClass());

return proxy;

}

//加入advisedBeans集合中

this.advisedBeans.put(cacheKey, Boolean.FALSE);

return bean;

}

/**

* 判斷什么是基礎(chǔ)的class

* */

protected boolean isInfrastructureClass(Class<?> beanClass) {

//判斷當(dāng)前的class是不是 Pointcut Advisor Advice AopInfrastructureBean 只要有一個(gè)滿(mǎn)足就返回true

boolean retVal = Advice.class.isAssignableFrom(beanClass) ||

Pointcut.class.isAssignableFrom(beanClass) ||

Advisor.class.isAssignableFrom(beanClass) ||

AopInfrastructureBean.class.isAssignableFrom(beanClass);

if (retVal && logger.isTraceEnabled()) {

logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");

}

return retVal;

}

4.3:>org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean

源碼分析

//找到符合條件的增強(qiáng)器

@Override

protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {

//查找符合條件的增強(qiáng)器

List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);

if (advisors.isEmpty()) {

return DO_NOT_PROXY;

}

return advisors.toArray();

}

4.4)org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findEligibleAdvisors

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {

//找到候選的增強(qiáng)器

List<Advisor> candidateAdvisors = findCandidateAdvisors();

//從候選的中選出能用的增強(qiáng)器

List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);

extendAdvisors(eligibleAdvisors);

if (!eligibleAdvisors.isEmpty()) {

eligibleAdvisors = sortAdvisors(eligibleAdvisors);

}

return eligibleAdvisors;

}

4.5)org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findCandidateAdvisors

從IOC容器中查找所有的增強(qiáng)器

protected List<Advisor> findCandidateAdvisors() {

//調(diào)用父類(lèi)獲取增強(qiáng)器

List<Advisor> advisors = super.findCandidateAdvisors();

//解析 @Aspect 注解艰毒,并構(gòu)建通知器

advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());

return advisors;

}

=========================================super.findCandidateAdvisors();=================================

public List<Advisor> findAdvisorBeans() {

//先從緩存中獲取增強(qiáng)器 cachedAdvisorBeanNames是advisor的名稱(chēng)

String[] advisorNames = this.cachedAdvisorBeanNames;

//緩存中沒(méi)有獲取到

if (advisorNames == null) {

//從IOC容器中獲取增強(qiáng)器的名稱(chēng)

advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(

this.beanFactory, Advisor.class, true, false);

//賦值給增強(qiáng)器緩存

this.cachedAdvisorBeanNames = advisorNames;

}

//在IOC容器中沒(méi)有獲取到直接返回

if (advisorNames.length == 0) {

return new ArrayList<Advisor>();

}

List<Advisor> advisors = new ArrayList<Advisor>();

//遍歷所有的增強(qiáng)器

for (String name : advisorNames) {

if (isEligibleBean(name)) {

//忽略正在創(chuàng)建的增強(qiáng)器

if (this.beanFactory.isCurrentlyInCreation(name)) {

if (logger.isDebugEnabled()) {

logger.debug("Skipping currently created advisor '" + name + "'");

}

}

else {

try {

//通過(guò)getBean的形式創(chuàng)建增強(qiáng)器 //并且將bean 添加到advisors中

advisors.add(this.beanFactory.getBean(name, Advisor.class));

}

catch (BeanCreationException ex) {

Throwable rootCause = ex.getMostSpecificCause();

if (rootCause instanceof BeanCurrentlyInCreationException) {

BeanCreationException bce = (BeanCreationException) rootCause;

if (this.beanFactory.isCurrentlyInCreation(bce.getBeanName())) {

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;

}

=============================================aspectJAdvisorsBuilder.buildAspectJAdvisors()解析@Aspject下面buildAspectJAdvisors這個(gè)方法為我們做了什么?

第一步:先從增強(qiáng)器緩存中獲取增強(qiáng)器對(duì)象

判斷緩存中有沒(méi)有增強(qiáng)器對(duì)象,有搜囱,那么直接從緩存中直接獲取返回出去

沒(méi)有.....從容器中獲取所有的beanName

遍歷上一步獲取所有的beanName,通過(guò)beanName獲取beanType

根據(jù)beanType判斷當(dāng)前bean是否是一個(gè)的Aspect注解類(lèi)丑瞧,若不是則不做任何處理

調(diào)用advisorFactory.getAdvisors獲取通知器

public List<Advisor> buildAspectJAdvisors() {

//先從緩存中獲取

List<String> aspectNames = this.aspectBeanNames;

//緩存中沒(méi)有獲取到

if (aspectNames == null) {

synchronized (this) {

//在嘗試從緩存中獲取一次

aspectNames = this.aspectBeanNames;

//還是沒(méi)有獲取到

if (aspectNames == null) {

//從容器中獲取所有的bean的name

List<Advisor> advisors = new LinkedList<Advisor>();

aspectNames = new LinkedList<String>();

String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(

this.beanFactory, Object.class, true, false);

//遍歷beanNames

for (String beanName : beanNames) {

if (!isEligibleBean(beanName)) {

continue;

}

//根據(jù)beanName獲取bean的類(lèi)型

Class<?> beanType = this.beanFactory.getType(beanName);

if (beanType == null) {

continue;

}

//檢查beanType是否包含Aspect

if (this.advisorFactory.isAspect(beanType)) {

aspectNames.add(beanName);

//創(chuàng)建一餓Aspect類(lèi)的源信息對(duì)象

AspectMetadata amd = new AspectMetadata(beanType, beanName);

if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {

MetadataAwareAspectInstanceFactory factory =

new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);

//從aspectj中獲取通知器

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();

}

//緩存中有增強(qiáng)器,我們從緩存中獲取返回出去

List<Advisor> advisors = new LinkedList<Advisor>();

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;

}

//獲取通知

===========org.springframework.aop.aspectj.annotation.AspectJAdvisorFactory#getAdvisors========

/**

*

*

* */

public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {

//獲取標(biāo)識(shí)了@AspectJ標(biāo)志的切面類(lèi)

Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();

//獲取切面的名稱(chēng)

String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();

validate(aspectClass);

// We need to wrap the MetadataAwareAspectInstanceFactory with a decorator

// so that it will only instantiate once.

MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =

new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);

List<Advisor> advisors = new ArrayList<Advisor>();

//獲取切面類(lèi)排除@PointCut標(biāo)志的所有方法

for (Method method : getAdvisorMethods(aspectClass)) {

//每一個(gè)方法都調(diào)用getAdvisor方法來(lái)獲取增強(qiáng)器

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;

}

//通過(guò)方法獲取增強(qiáng)器

public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,

int declarationOrderInAspect, String aspectName) {

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

//獲取aspectj的切點(diǎn)表達(dá)式

AspectJExpressionPointcut expressionPointcut = getPointcut(

candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());

if (expressionPointcut == null) {

return null;

}

//創(chuàng)建advisor實(shí)現(xiàn)類(lèi)

return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,

this, aspectInstanceFactory, declarationOrderInAspect, aspectName);

}

//獲取切點(diǎn)表達(dá)式

private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {

//獲取切面注解 @Before @After蜀肘。绊汹。。扮宠。西乖。。

AspectJAnnotation<?> aspectJAnnotation =

AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);

if (aspectJAnnotation == null) {

return null;

}

//獲取切點(diǎn)表達(dá)式對(duì)象

AspectJExpressionPointcut ajexp =

new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);

//設(shè)置切點(diǎn)表達(dá)式

ajexp.setExpression(aspectJAnnotation.getPointcutExpression());

ajexp.setBeanFactory(this.beanFactory);

return ajexp;

}

//找到切面類(lèi)中方法上的切面注解

protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {

//Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class

for (Class<?> clazz : ASPECTJ_ANNOTATION_CLASSES) {

AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) clazz);

if (foundAnnotation != null) {

return foundAnnotation;

}

}

return null;

}

//把切點(diǎn),候選的方法....統(tǒng)一處理生成一個(gè)增強(qiáng)器

public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,

Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,

MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {

this.declaredPointcut = declaredPointcut;

this.declaringClass = aspectJAdviceMethod.getDeclaringClass();

this.methodName = aspectJAdviceMethod.getName();

this.parameterTypes = aspectJAdviceMethod.getParameterTypes();

this.aspectJAdviceMethod = aspectJAdviceMethod;

this.aspectJAdvisorFactory = aspectJAdvisorFactory;

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;

//實(shí)例化切面

this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);

}

}

//獲取advice 切面對(duì)象

public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,

MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {

//獲取候選的切面類(lèi)

Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();

validate(candidateAspectClass);

//獲取切面注解

AspectJAnnotation<?> aspectJAnnotation =

AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);

if (aspectJAnnotation == null) {

return null;

}

// If we get here, we know we have an AspectJ method.

// Check that it's an AspectJ-annotated class

if (!isAspect(candidateAspectClass)) {

throw new AopConfigException("Advice must be declared inside an aspect type: " +

"Offending method '" + candidateAdviceMethod + "' in class [" +

candidateAspectClass.getName() + "]");

}

if (logger.isDebugEnabled()) {

logger.debug("Found AspectJ method: " + candidateAdviceMethod);

}

AbstractAspectJAdvice springAdvice;

//判斷注解的類(lèi)型

switch (aspectJAnnotation.getAnnotationType()) {

//是切點(diǎn)的返回null

case AtPointcut:

if (logger.isDebugEnabled()) {

logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");

}

return null;

//是不是環(huán)繞通知

case AtAround:

springAdvice = new AspectJAroundAdvice(

candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);

break;

//是不是前置通知

case AtBefore:

springAdvice = new AspectJMethodBeforeAdvice(

candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);

break;

//是不是后置通知

case AtAfter:

springAdvice = new AspectJAfterAdvice(

candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);

break;

//返回通知

case AtAfterReturning:

springAdvice = new AspectJAfterReturningAdvice(

candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);

AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();

if (StringUtils.hasText(afterReturningAnnotation.returning())) {

springAdvice.setReturningName(afterReturningAnnotation.returning());

}

break;

是不是異常通知

case AtAfterThrowing:

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

}

// Now to configure the advice...

springAdvice.setAspectName(aspectName);

springAdvice.setDeclarationOrder(declarationOrder);

/*

* 獲取方法的參數(shù)列表名稱(chēng)获雕,比如方法 int sum(int numX, int numY),

* getParameterNames(sum) 得到 argNames = [numX, numY]

*/

String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);

if (argNames != null) {

//為切面設(shè)置參數(shù)

springAdvice.setArgumentNamesFromStringArray(argNames);

}

springAdvice.calculateArgumentBindings();

return springAdvice;

}

4.6:)>org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findAdvisorsThatCanApply

//獲取能夠使用的增強(qiáng)器

protected List<Advisor> findAdvisorsThatCanApply(

List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

ProxyCreationContext.setCurrentProxiedBeanName(beanName);

try {

return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);

}

finally {

ProxyCreationContext.setCurrentProxiedBeanName(null);

}

}

//獲取能使用的增強(qiáng)器

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {

if (candidateAdvisors.isEmpty()) {

return candidateAdvisors;

}

List<Advisor> eligibleAdvisors = new LinkedList<Advisor>();

//遍歷候選的增強(qiáng)器 把他增加到eligibleAdvisors集合中返回

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;

}

if (canApply(candidate, clazz, hasIntroductions)) {

eligibleAdvisors.add(candidate);

}

}

return eligibleAdvisors;

}

//判斷是當(dāng)前的增強(qiáng)器是否能用 通過(guò)方法匹配來(lái)計(jì)算當(dāng)前是否合適當(dāng)前類(lèi)的增強(qiáng)器

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;

return canApply(pca.getPointcut(), targetClass, hasIntroductions);

}

else {

// It doesn't have a pointcut so we assume it applies.

return true;

}

}

public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {

Assert.notNull(pc, "Pointcut must not be null");

if (!pc.getClassFilter().matches(targetClass)) {

return false;

}

//創(chuàng)建一個(gè)方法匹配器

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 = null;

if (methodMatcher instanceof IntroductionAwareMethodMatcher) {

introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;

}

//獲取本來(lái)和接口

Set<Class<?>> classes = new LinkedHashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));

classes.add(targetClass);

//循環(huán)classes

for (Class<?> clazz : classes) {

//獲取所有的方法 進(jìn)行匹配

Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);

for (Method method : methods) {

if ((introductionAwareMethodMatcher != null &&

introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||

methodMatcher.matches(method, targetClass)) {

return true;

}

}

}

return false;

}

4.5)org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy創(chuàng)建代理對(duì)象

protected Object createProxy(

Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {

//判斷容器的類(lèi)型ConfigurableListableBeanFactory

if (this.beanFactory instanceof ConfigurableListableBeanFactory) {

AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);

}

//創(chuàng)建代理工程

ProxyFactory proxyFactory = new ProxyFactory();

proxyFactory.copyFrom(this);

/*

* 默認(rèn)配置下薄腻,或用戶(hù)顯式配置 proxy-target-class = "false" 時(shí),

* 這里的 proxyFactory.isProxyTargetClass() 也為 false

*/

if (!proxyFactory.isProxyTargetClass()) {

if (shouldProxyTargetClass(beanClass, beanName)) {

proxyFactory.setProxyTargetClass(true);

}

else {

/*

* 檢測(cè) beanClass 是否實(shí)現(xiàn)了接口届案,若未實(shí)現(xiàn)庵楷,則將

* proxyFactory 的成員變量 proxyTargetClass 設(shè)為 true

*/

evaluateProxyInterfaces(beanClass, proxyFactory);

}

}

//獲取容器中的方法增強(qiáng)器

Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);

proxyFactory.addAdvisors(advisors);

proxyFactory.setTargetSource(targetSource);

customizeProxyFactory(proxyFactory);

proxyFactory.setFrozen(this.freezeProxy);

if (advisorsPreFiltered()) {

proxyFactory.setPreFiltered(true);

}

//創(chuàng)建代理對(duì)象

return proxyFactory.getProxy(getProxyClassLoader());

}

public Object getProxy(ClassLoader classLoader) {

return createAopProxy().getProxy(classLoader);

}

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {

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.");

}

//是否實(shí)現(xiàn)了接口

if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {

//jdk代理

return new JdkDynamicAopProxy(config);

}

//cglib代理

return new ObjenesisCglibAopProxy(config);

}

else {

jdk代理

return new JdkDynamicAopProxy(config);

}

}

public Object getProxy(ClassLoader classLoader) {

if (logger.isDebugEnabled()) {

logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());

}

Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);

findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);

//創(chuàng)建jdk代理對(duì)象

return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);

}

5:代理對(duì)象調(diào)用目標(biāo)方法

背景知識(shí):

@EnableAspectJAutoProxy(exposeProxy = true) 這個(gè)東東是用來(lái)干什么的?

沒(méi)有配置exposeProxy 暴露代理對(duì)象的時(shí)候我們方法調(diào)用

我們?cè)贛od方法中 通過(guò)this來(lái)調(diào)用本類(lèi)的方法add()方法的時(shí)候楣颠,發(fā)現(xiàn)add()的方法不會(huì)被攔截

而我們配置了后exposeProxy的屬性尽纽,我們發(fā)現(xiàn)可以通過(guò)

int retVal = ((Calculate) AopContext.currentProxy()).add(numA,numB);

調(diào)用的時(shí)候,發(fā)現(xiàn)了add()方法可以被攔截

原理:把這個(gè)exposeProxy設(shè)置為true童漩,會(huì)把代理對(duì)象存放在線程變量中,

AopContext.currentProxy())是從線程變量中獲取代理對(duì)象(源碼中分析)

應(yīng)用場(chǎng)景(事物方法調(diào)用事物方法需要二個(gè)都起作用需要配置這個(gè)東東)

public interface Calculate {

/**

* 加法

* @param numA

* @param numB

* @return

*/

int add(int numA,int numB);

/**

* 減法

* @param numA

* @param numB

* @return

*/

int reduce(int numA,int numB);

/**

* 除法

* @param numA

* @param numB

* @return

*/

int div(int numA,int numB);

/**

* 乘法

* @param numA

* @param numB

* @return

*/

int multi(int numA,int numB);

int mod(int numA,int numB);

}

public class TulingCalculate implements Calculate {

public int add(int numA, int numB) {

return numA+numB;

}

public int reduce(int numA, int numB) {

return numA-numB;

}

public int div(int numA, int numB) {

return numA/numB;

}

public int multi(int numA, int numB) {

return numA*numB;

}

public int mod(int numA,int numB){

int retVal = ((Calculate) AopContext.currentProxy()).add(numA,numB);

//int retVal = this.add(numA,numB);

return retVal%numA;

}

}

代理對(duì)象調(diào)用源代碼:

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

MethodInvocation invocation;

Object oldProxy = null;

boolean setProxyContext = false;

TargetSource targetSource = this.advised.targetSource;

Class<?> targetClass = null;

Object target = null;

try {

Object retVal;

//是否暴露代理對(duì)象

if (this.advised.exposeProxy) {

//把代理對(duì)象添加到TheadLocal中

oldProxy = AopContext.setCurrentProxy(proxy);

setProxyContext = true;

}

//獲取被代理對(duì)象

target = targetSource.getTarget();

if (target != null) {

//設(shè)置被代理對(duì)象的class

targetClass = target.getClass();

}

//把增強(qiáng)器轉(zhuǎn)為方法攔截器鏈

List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

//若方法攔截器鏈為空

if (chain.isEmpty()) {

//通過(guò)反射直接調(diào)用目標(biāo)方法

Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);

retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);

}

else {

//創(chuàng)建方法攔截器調(diào)用鏈條

invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);

//執(zhí)行攔截器鏈

retVal = invocation.proceed();

}

//獲取方法的返回值類(lèi)型

Class<?> returnType = method.getReturnType();

if (retVal != null && retVal == target &&

returnType != Object.class && returnType.isInstance(proxy) &&

!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {

//如果方法返回值為 this弄贿,即 return this; 則將代理對(duì)象 proxy 賦值給 retVal

retVal = proxy;

}

//如果返回值類(lèi)型為基礎(chǔ)類(lèi)型,比如 int矫膨,long 等挎春,當(dāng)返回值為 null,拋出異常

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

}

}

}

=====================org.springframework.aop.framework.AdvisedSupport#getInterceptorsAndDynamicInterceptionAdvice===========

把增強(qiáng)器中轉(zhuǎn)為方法攔截器鏈

public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {

//從緩存中獲取緩存key 第一次肯定獲取不到

MethodCacheKey cacheKey = new MethodCacheKey(method);

//通過(guò)cacheKey獲取緩存值

List<Object> cached = this.methodCache.get(cacheKey);

//從緩存中沒(méi)有獲取到

if (cached == null) {

//獲取所有的攔截器

cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(

this, method, targetClass);

//放入緩存.....

this.methodCache.put(cacheKey, cached);

}

return cached;

}

=====================org.springframework.aop.framework.AdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice====

public List<Object> getInterceptorsAndDynamicInterceptionAdvice(

Advised config, Method method, Class<?> targetClass) {

//創(chuàng)建攔截器集合長(zhǎng)度是增強(qiáng)器的長(zhǎng)度

List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);

Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());

boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);

AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();

//遍歷所有的增強(qiáng)器集合

for (Advisor advisor : config.getAdvisors()) {

//判斷增強(qiáng)器是不是PointcutAdvisor

if (advisor instanceof PointcutAdvisor) {

//把增強(qiáng)器轉(zhuǎn)為PointcutAdvisor

PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;

//通過(guò)方法匹配器對(duì)增強(qiáng)器進(jìn)行匹配

if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {

MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();

//能夠匹配

if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {

//把增強(qiáng)器轉(zhuǎn)為攔截器

MethodInterceptor[] interceptors = registry.getInterceptors(advisor);

if (mm.isRuntime()) {

// Creating a new object instance in the getInterceptors() method

// isn't a problem as we normally cache created chains.

for (MethodInterceptor interceptor : interceptors) {

interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));

}

}

else {

interceptorList.addAll(Arrays.asList(interceptors));

}

}

}

}

else if (advisor instanceof IntroductionAdvisor) {

IntroductionAdvisor ia = (IntroductionAdvisor) advisor;

if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {

Interceptor[] interceptors = registry.getInterceptors(advisor);

interceptorList.addAll(Arrays.asList(interceptors));

}

}

else {

Interceptor[] interceptors = registry.getInterceptors(advisor);

interceptorList.addAll(Arrays.asList(interceptors));

}

}

return interceptorList;

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末豆拨,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子能庆,更是在濱河造成了極大的恐慌施禾,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,273評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件搁胆,死亡現(xiàn)場(chǎng)離奇詭異弥搞,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)渠旁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門(mén)攀例,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人顾腊,你說(shuō)我怎么就攤上這事粤铭。” “怎么了杂靶?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,709評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵梆惯,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我吗垮,道長(zhǎng)垛吗,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,520評(píng)論 1 296
  • 正文 為了忘掉前任烁登,我火速辦了婚禮怯屉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己锨络,他們只是感情好赌躺,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著足删,像睡著了一般寿谴。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上失受,一...
    開(kāi)封第一講書(shū)人閱讀 52,158評(píng)論 1 308
  • 那天讶泰,我揣著相機(jī)與錄音,去河邊找鬼拂到。 笑死痪署,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的兄旬。 我是一名探鬼主播狼犯,決...
    沈念sama閱讀 40,755評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼领铐!你這毒婦竟也來(lái)了悯森?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,660評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤绪撵,失蹤者是張志新(化名)和其女友劉穎瓢姻,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體音诈,經(jīng)...
    沈念sama閱讀 46,203評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡幻碱,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了细溅。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片褥傍。...
    茶點(diǎn)故事閱讀 40,427評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖喇聊,靈堂內(nèi)的尸體忽然破棺而出恍风,到底是詐尸還是另有隱情,我是刑警寧澤誓篱,帶...
    沈念sama閱讀 36,122評(píng)論 5 349
  • 正文 年R本政府宣布邻耕,位于F島的核電站,受9級(jí)特大地震影響燕鸽,放射性物質(zhì)發(fā)生泄漏兄世。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評(píng)論 3 333
  • 文/蒙蒙 一啊研、第九天 我趴在偏房一處隱蔽的房頂上張望御滩。 院中可真熱鬧鸥拧,春花似錦、人聲如沸削解。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,272評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)氛驮。三九已至腕柜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間矫废,已是汗流浹背盏缤。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蓖扑,地道東北人唉铜。 一個(gè)月前我還...
    沈念sama閱讀 48,808評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像律杠,于是被迫代替她去往敵國(guó)和親潭流。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容