1. 入口
SpringAOP的使用中有這么一個注解@EnableAspectJAutoProxy,按照Spring源碼的一貫套路,進入這個注解看一下源碼。重點關(guān)注這一行。
@Import(AspectJAutoProxyRegistrar.class)
查看該類
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
/**
* Register, escalate, and configure the AspectJ auto proxy creator based on the value
* of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
* {@code @Configuration} class.
*/
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 注冊 名字internalAutoProxyCreator的 AnnotationAwareAspectJAutoProxyCreator
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
// 獲得注解的屬性
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
//根據(jù)其中的 proxyTargetClass/exposeProxy 設(shè)置beanDefinition屬性
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}
最終會調(diào)用AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary方法,注冊一個AnnotationAwareAspectJAutoProxyCreator,該類屬于AOP的核心類。
2. 整體流程
首先我們先想下,如果讓我們自己實現(xiàn),我們需要做些什么。
- 先查找切面
- 對切面進行解析
- 從切面中拿到所有的增強方法(@Befor、@After)
- 拿到這些解析創(chuàng)建代理,如果該類實現(xiàn)了接口,就用動態(tài)代理,沒有接口就用CGLIB代理
- 最后調(diào)用@Advise里的那些@Before、@After方法
那么順著這個思路,開始看源碼。
2.1 查找切面
現(xiàn)在我們有了AnnotationAwareAspectJAutoProxyCreator這個類,查看該類的繼承關(guān)系圖。(省略一些不必要的類)。

首先看第一個接口,BeanPostProcessor,這個接口作為頂層接口,肯定不會被外部直接調(diào)用,所以大概率是底下的幾個具體實現(xiàn)類被調(diào)用,然后通過判斷是不是InstantiationAwareBeanPostProcessor接口的類型,再執(zhí)行相應(yīng)邏輯,帶著這個疑惑,來看源碼。
2.1.1 AnnotationConfigApplicationContext.refresh()
如果之前看過SpringIOC的源碼篇的,應(yīng)該記得,Spring最核心的就是Bean,所以如果要調(diào)用Bean的邏輯的話,肯定會在創(chuàng)建Bean之后,也就是creatBean方法以后,那么我們先看AnnotationConfigApplicationContext.refresh()這個方法。
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//1:準(zhǔn)備刷新上下文環(huán)境
prepareRefresh();
//2:獲取告訴子類初始化Bean工廠 不同工廠不同實現(xiàn)
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//3:對bean工廠進行填充屬性
prepareBeanFactory(beanFactory);
try {
// 第四:留個子類去實現(xiàn)該接口
postProcessBeanFactory(beanFactory);
// 調(diào)用我們的bean工廠的后置處理器. 1. 會在此將class掃描成beanDefinition 2.bean工廠的后置處理器調(diào)用
invokeBeanFactoryPostProcessors(beanFactory);
// 注冊我們bean的后置處理器
registerBeanPostProcessors(beanFactory);
// 初始化國際化資源處理器.
initMessageSource();
// 創(chuàng)建事件多播器
initApplicationEventMulticaster();
// 這個方法同樣也是留個子類實現(xiàn)的springboot也是從這個方法進行啟動tomcat的.
onRefresh();
//把我們的事件監(jiān)聽器注冊到多播器上
registerListeners();
// 實例化我們剩余的單實例bean.
finishBeanFactoryInitialization(beanFactory);
// 最后容器刷新 發(fā)布刷新事件(Spring cloud也是從這里啟動的)
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
2.1.2 finishBeanFactoryInitialization(beanFactory)
看finishBeanFactoryInitialization(beanFactory)這個方法。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 為我們的bean工廠創(chuàng)建類型轉(zhuǎn)化器 Convert
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
/**
* public class MainConfig implements EmbeddedValueResolverAware{
*
* public void setEmbeddedValueResolver(StringValueResolver resolver) {
this.jdbcUrl = resolver.resolveStringValue("${ds.jdbcUrl}");
this.classDriver = resolver.resolveStringValue("${ds.classDriver}");
}
}
*/
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// 處理關(guān)于aspectj
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
//凍結(jié)所有的 bean 定義 , 說明注冊的 bean 定義將不被修改或任何進一步的處理
beanFactory.freezeConfiguration();
//實例化剩余的單實例bean
beanFactory.preInstantiateSingletons();
}
2.1.3 beanFactory.preInstantiateSingletons()
public void preInstantiateSingletons() throws BeansException {
if (logger.isDebugEnabled()) {
logger.debug("Pre-instantiating singletons in " + this);
}
//獲取我們?nèi)萜髦兴衎ean定義的名稱
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
//循環(huán)我們所有的bean定義名稱
for (String beanName : beanNames) {
//合并我們的bean定義,轉(zhuǎn)換為統(tǒng)一的RootBeanDefinition類型(在), 方便后續(xù)處理
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
/**
* 根據(jù)bean定義判斷是不是抽象的&& 不是單例的 &&不是懶加載的
*/
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//是不是工廠bean
if (isFactoryBean(beanName)) {
// 是factoryBean會先生成實際的bean &beanName 是用來獲取實際bean的
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
//調(diào)用真正的getBean的流程
if (isEagerInit) {
getBean(beanName);
}
}
}
else {//非工廠Bean 就是普通的bean
getBean(beanName);
}
}
}
//或有的bean的名稱 ...........到這里所有的單實例的bean已經(jīng)記載到單實例bean到緩存中
for (String beanName : beanNames) {
//從單例緩存池中獲取所有的對象
Object singletonInstance = getSingleton(beanName);
//判斷當(dāng)前的bean是否實現(xiàn)了SmartInitializingSingleton接口
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
//觸發(fā)實例化之后的方法afterSingletonsInstantiated
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
2.1.4 getBean(beanName)方法
/**
* 該方法是一個空殼方法,沒有任何的實現(xiàn)邏輯 真正的邏輯調(diào)用在doGetBean()中
* 該接口是實現(xiàn)了BeanFactory的getBean(String name)接口
* @param name bean的名稱 該名稱也有可能是bean的alies(別名)
* @return 我們的單例對象
* @throws BeansException
*/
@Override
public Object getBean(String name) throws BeansException {
//真正的獲取bean的邏輯
return doGetBean(name, null, null, false);
}
2.1.5 doGetBean(name, null, null, false)方法
重點看該方法里的createBean方法。
2.1.6 creatBean
重點看這里
try {
/**
* 第1個bean后置處理器
* 通過bean的后置處理器來進行后置處理生成代理對象,一般情況下在此處不會生成代理對象
* 為什么不能生成代理對象,不管是我們的jdk代理還是cglib代理都不會在此處進行代理,因為我們的
* 真實的對象沒有生成,所以在這里不會生成代理對象,那么在這一步是我們aop和事務(wù)的關(guān)鍵,因為在這里
* 解析我們的aop切面信息進行緩存
*/
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
2.1.7 resolveBeforeInstantiation方法
到此,找到了判斷容器中有沒有InstantiationAwareBeanPostProcessors了,那么繼續(xù)看。
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
//判斷容器中是否有InstantiationAwareBeanPostProcessors
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
//獲取當(dāng)前bean 的class對象
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
/**
* 后置處理器的【第一次】調(diào)用 總共有九處調(diào)用 事務(wù)在這里不會被調(diào)用,aop的才會被調(diào)用
* 為啥aop在這里調(diào)用了,因為在此處需要解析出對應(yīng)的切面報錯到緩存中
*/
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
//若InstantiationAwareBeanPostProcessors后置處理器的postProcessBeforeInstantiation返回不為null
//說明生成了代理對象那么我們就調(diào)用
if (bean != null) {
/**
* 后置處理器的第二處調(diào)用,該后置處理器若被調(diào)用的話,那么第一處的處理器肯定返回的不是null
* InstantiationAwareBeanPostProcessors后置處理器postProcessAfterInitialization
*/
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
2.1.8 applyBeanPostProcessorsBeforeInstantiation
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
/**
* 獲取容器中的所有后置處理器
*/
for (BeanPostProcessor bp : getBeanPostProcessors()) {
//判斷后置處理器是不是InstantiationAwareBeanPostProcessor
if (bp instanceof InstantiationAwareBeanPostProcessor) {
//把我們的BeanPostProcessor強制轉(zhuǎn)為InstantiationAwareBeanPostProcessor
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
/**
* 【很重要】
* 我們AOP @EnableAspectJAutoProxy 為我們?nèi)萜髦袑?dǎo)入了 AnnotationAwareAspectJAutoProxyCreator
* 我們事務(wù)注解@EnableTransactionManagement 為我們的容器導(dǎo)入了 InfrastructureAdvisorAutoProxyCreator
* 都是實現(xiàn)了我們的 BeanPostProcessor接口,InstantiationAwareBeanPostProcessor,
* 進行后置處理解析切面
*/
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
2.1.9 postProcessBeforeInstantiation方法
重點看這里
/**
* 注意看重寫方法
* 判斷是不是基礎(chǔ)的bean (是不是切面類、通知、切點等)
* 判斷是不是應(yīng)該跳過 默認(rèn)false (切面解析也在其中)
*/
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
2.1.10 shouldSkip方法
終于到了AnnotationAwareAspectJAutoProxyCreator.shouldSkip方法了。
@Override
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
/**
* 找到候選的Advisors(通知 前置通知、后置通知等..)
*/
List<Advisor> candidateAdvisors = findCandidateAdvisors();
for (Advisor advisor : candidateAdvisors) {
// 判斷這個類的原因在于:
// AspectJPointcutAdvisor 是xml <aop:advisor 解析的對象
// 如果 <aop:aspect ref="beanName"> 是當(dāng)前beanName 就說明當(dāng)前bean是切面類 那就跳過。
if (advisor instanceof AspectJPointcutAdvisor &&
((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
return true;
}
}
return super.shouldSkip(beanClass, beanName);
}
2.1.11 findCandidateAdvisors()方法
/**
* 這里會找 兩種通知方式:
* Advisor代理方式 (@Transactional底層的方式)
* AspectJ增強方式
* @return
*/
@Override
protected List<Advisor> findCandidateAdvisors() {
// 找出xml配置的Advisor和原生接口的AOP的Advisor 找出事務(wù)相關(guān)的advisor
List<Advisor> advisors = super.findCandidateAdvisors();
//找出Aspect相關(guān)的信息之后封裝為一個advisor
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
//返回我們所有的通知
return advisors;
}
2.1.12 buildAspectJAdvisors方法
這里可以看到,Spring里用了緩存advisorsCache來保存通知對象。
/**
* 去容器中獲取到所有的切面信息保存到緩存中
* @return the list of {@link org.springframework.aop.Advisor} beans
* @see #isEligibleBean
*/
public List<Advisor> buildAspectJAdvisors() {
/**
* 用于保存切面的名稱,該地方aspectNames 是我們的類級別的緩存,用戶緩存已經(jīng)解析出來的切面信息
*/
List<String> aspectNames = this.aspectBeanNames;
// 緩存字段aspectNames沒有值 會在第一個單例執(zhí)行后置處理器(AnnotationAwareAspectJAutoProxyCreator注冊之后)的時候就會觸發(fā)解析切面的操作
if (aspectNames == null) {
// 加上同步鎖, 防止多線程同時加載Aspect
synchronized (this) {
aspectNames = this.aspectBeanNames;
//做了雙重檢查加鎖
if (aspectNames == null) {
// 保存所有通知的集合
List<Advisor> advisors = new ArrayList<>();
// 保存切面的名稱的集合
aspectNames = new ArrayList<>();
/**
* aop功能中在這里傳入的是Object.class,代表去容器中獲取到所有的組件的名稱,然后再經(jīng)過
* 一一的進行遍歷,這個過程是十分的消耗性能的,所以說spring會再這里加入了保存切面信息的緩存。
* 但是事務(wù)功能不一樣,事務(wù)模塊的功能是直接去容器中獲取Advisor類型的,選擇范圍小,且不消耗性能。所以
* spring在事務(wù)模塊中沒有加入緩存來保存我們的事務(wù)相關(guān)的advisor
*/
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
//遍歷我們從IOC容器中獲取處的所有bean的名稱
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
}
//通過beanName去容器中獲取到對應(yīng)class對象
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
//根據(jù)class對象判斷是不是切面
if (this.advisorFactory.isAspect(beanType)) {
//是切面類
//加入到緩存中
aspectNames.add(beanName);
//把beanName和class對象構(gòu)建成為一個AspectMetadata
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
//構(gòu)建切面注解的實例工廠
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
//真正的去獲取我們的通知對象
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();
}
/**
* 真正的創(chuàng)建切面的時候,我們不需要去解析了而是直接去緩存中獲取處
*/
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;
}
至此切面解析的全過程,分析完畢。
2.2 創(chuàng)建代理
讓我們再回到AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation方法中
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
//判斷容器中是否有InstantiationAwareBeanPostProcessors
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
//獲取當(dāng)前bean 的class對象
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
/**
* 后置處理器的【第一次】調(diào)用 總共有九處調(diào)用 事務(wù)在這里不會被調(diào)用,aop的才會被調(diào)用
* 為啥aop在這里調(diào)用了,因為在此處需要解析出對應(yīng)的切面報錯到緩存中
*/
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
//若InstantiationAwareBeanPostProcessors后置處理器的postProcessBeforeInstantiation返回不為null
//說明生成了代理對象那么我們就調(diào)用
if (bean != null) {
/**
* 后置處理器的第二處調(diào)用,該后置處理器若被調(diào)用的話,那么第一處的處理器肯定返回的不是null
* InstantiationAwareBeanPostProcessors后置處理器postProcessAfterInitialization
*/
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
前邊已經(jīng)分析完了后置處理器的第一次調(diào)用,完成了解析AOP切面的功能。下面來看看第二次調(diào)用。
2.2.1 applyBeanPostProcessorsAfterInitialization方法
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
//獲取我們?nèi)萜髦械乃械腷ean的后置處理器
for (BeanPostProcessor processor : getBeanPostProcessors()) {
/**
* 在這里是后置處理器的【第九次調(diào)用】 aop和事務(wù)都會在這里生存代理對象
*
* 【很重要】
* 我們AOP @EnableAspectJAutoProxy 為我們?nèi)萜髦袑?dǎo)入了 AnnotationAwareAspectJAutoProxyCreator
* 我們事務(wù)注解@EnableTransactionManagement 為我們的容器導(dǎo)入了 InfrastructureAdvisorAutoProxyCreator
* 都是實現(xiàn)了我們的 BeanPostProcessor接口,InstantiationAwareBeanPostProcessor,
* 在這里實現(xiàn)的是BeanPostProcessor接口的postProcessAfterInitialization來生成我們的代理對象
*/
Object current = processor.postProcessAfterInitialization(result, beanName);
//若只有有一個返回null 那么直接返回原始的
if (current == null) {
return result;
}
result = current;
}
return result;
}
2.2.2 AbstractAutoProxyCreator.postProcessAfterInitialization方法
/**
* 生成aop代理
* 在該后置方法中 我們的事務(wù)和aop的代理對象都是在這生成的
* @param bean bean實例
* @param beanName bean的名稱
* @return
* @throws BeansException
*/
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
if (bean != null) {
//獲取緩存key
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 之前循環(huán)依賴創(chuàng)建的動態(tài)代理 如果是現(xiàn)在的bean 就不再創(chuàng)建,,并且移除
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 該方法將會返回動態(tài)代理實例
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
2.2.3 wrapIfNecessary方法
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//已經(jīng)被處理過(解析切面時targetSourcedBeans出現(xiàn)過) 就是自己實現(xiàn)創(chuàng)建動態(tài)代理邏輯
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
//不需要增強的
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
//是不是基礎(chǔ)的bean 是不是需要跳過的 重復(fù)判斷 ( 因為循環(huán)依賴是可以改變bean的,如果把bean改成了advisor呢)
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 根據(jù)當(dāng)前bean找到匹配的advisor
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 當(dāng)前bean匹配到了advisor
if (specificInterceptors != DO_NOT_PROXY) {
// 標(biāo)記為已處理
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//創(chuàng)建我們的真正的代理對象
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
//加入到緩存
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
2.2.4 createProxy
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);
}
//創(chuàng)建一個代理對象工廠
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
//為proxyFactory設(shè)置創(chuàng)建jdk代理還是cglib代理
// 如果設(shè)置了 <aop:aspectj-autoproxy proxy-target-class="true"/>不會進if,說明強制使用cglib
if (!proxyFactory.isProxyTargetClass()) {
// 內(nèi)部設(shè)置的 , 配置類就會設(shè)置這個屬性
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
// 檢查有沒有接口
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
//把我們的specificInterceptors數(shù)組中的Advisor轉(zhuǎn)化為數(shù)組形式的
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
//為我們的代理工廠加入通知器,
proxyFactory.addAdvisors(advisors);
//設(shè)置targetSource對象
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
// 代表之前是否篩選advise.
// 因為繼承了AbstractAdvisorAutoProxyCreator , 并且之前調(diào)用了findEligibleAdvisors進行篩選, 所以是true
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
//真正的創(chuàng)建代理對象
return proxyFactory.getProxy(getProxyClassLoader());
}
2.2.5 getProxy
public Object getProxy(@Nullable ClassLoader classLoader) {
//createAopProxy() 用來獲取我們的代理工廠
return createAopProxy().getProxy(classLoader);
}
2.2.6 DefaultAopProxyFactory.createAopProxy
這個方法就是AOP創(chuàng)建代理的核心方法,有接口就用JDK動態(tài)代理,沒有接口就用CGLIB代理。
/**
*
* @param config 用來為我們指定我們advisor信息
* 該方法用來創(chuàng)建我們的代理對象
* 所我們的targetClass對象實現(xiàn)了接口,且 ProxyTargetClass 沒有指定強制的走cglib代理,那么就是創(chuàng)建jdk代理
* 我們代理的類沒有實現(xiàn)接口,那么會直接走cglib代理
* 若我們 ProxyTargetClass 指定為false 且代理類是接口才會走jdk代理 否在我們還是cglib代理
* @return
* @throws AopConfigException
*/
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
//判斷我們是否前置指定使用cglib代理ProxyTargetClass =true 或者沒有接口
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.");
}
//所targetClass是接口 使用的就是jdk代理
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
//cglib代理
return new ObjenesisCglibAopProxy(config);
}
else {
//動態(tài)代理
return new JdkDynamicAopProxy(config);
}
}
至此所有代碼分析完畢。