天天看點

Spring AOP源碼解析(二)—— AOP引入配置類代理生成

目錄

配置類

AopAutoConfiguration  

AspectJAutoProxyingConfiguration 

ClassProxyingConfiguration 

@EnableAspectJAutoProxy

AspectJAutoProxyRegistrar

AopConfigUtils

代理生成

AnnotationAwareAspectJAutoProxyCreator

Aware 

 BeanPostProcessor 

AopInfrastructureBean  

ProxyConfig

 ProxyProcessorSupport

AbstractAutoProxyCreator

屬性

Aware實作 

BeanPostProcessor實作

InstantiationAwareBeanPostProcessor實作 

SmartInstantiationAwareBeanPostProcessor實作 

wrapIfNecessary

createProxy

buildAdvisors

AbstractAdvisorAutoProxyCreator

BeanFactoryAdvisorRetrievalHelper

AspectJAwareAdvisorAutoProxyCreator

 extendAdvisors

AspectJProxyUtils 

AnnotationAwareAspectJAutoProxyCreator

覆寫父類:findCandidateAdvisors

BeanFactoryAspectJAdvisorsBuilder

DefaultAdvisorAutoProxyCreator

InfrastructureAdvisorAutoProxyCreator

AOP是怎麼生效的呢?在spring boot項目spring-boot-autoconfigure中spring.factories檔案配置了自動導入:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
... ... 
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
           

配置類

AopAutoConfiguration  

@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {
}
           

當配置spring.aop.auto=true時(true為預設值),則導入配置。AopAutoConfiguration  内部又定義了2個配置類。

AspectJAutoProxyingConfiguration 

AspectJAutoProxyingConfiguration 在定義了Advice才會導入。并且實作了2種可替換模式:JDK動态代理和cglib代理。通過spring.aop.proxy-target-class屬性控制。如果沒有指定,則2種模式互相配置,有接口的用動态代理,沒有接口用cglib,如果指定了值,則使用指定了的方式代理對象。

@Configuration(proxyBeanMethods = false)
	@ConditionalOnClass(Advice.class)
	static class AspectJAutoProxyingConfiguration {

		@Configuration(proxyBeanMethods = false)
		@EnableAspectJAutoProxy(proxyTargetClass = false)
		@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false",
				matchIfMissing = false)
		static class JdkDynamicAutoProxyConfiguration {

		}

		@Configuration(proxyBeanMethods = false)
		@EnableAspectJAutoProxy(proxyTargetClass = true)
		@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
				matchIfMissing = true)
		static class CglibAutoProxyConfiguration {

		}

	}
           

ClassProxyingConfiguration 

配置使用cglib動态代理的情況下,如果沒有引入org.aspectj.weaver.Advice時的代理方式。

@Configuration(proxyBeanMethods = false)
	@ConditionalOnMissingClass("org.aspectj.weaver.Advice")
	@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
			matchIfMissing = true)
	static class ClassProxyingConfiguration {

		ClassProxyingConfiguration(BeanFactory beanFactory) {
			if (beanFactory instanceof BeanDefinitionRegistry) {
				BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
				AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
				AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
			}
		}

	}
           

@EnableAspectJAutoProxy

導入了AspectJAutoProxyRegistrar。用于注冊自動生成代理。

@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {

	/**是否采用cglib方式*/
	boolean proxyTargetClass() default false;

	/**是否ThreadLocal 類型。
    * @since 4.3.1
	 */
	boolean exposeProxy() default false;

}
           

AspectJAutoProxyRegistrar

AspectJAutoProxyRegistrar用于注冊AutoProxy。第1部分将AnnotationAwareAspectJAutoProxyCreator類型包裝成BeanDefinition注冊到Spring容器。第2部分将proxyTargetClass的配置設定到此BeanDefinition裡。

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

	@Override
	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//1
		AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
//2
		AnnotationAttributes enableAspectJAutoProxy =
				AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
		if (enableAspectJAutoProxy != null) {
			if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
				AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
			}
			if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
				AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
			}
		}
	}

}
           

AopConfigUtils

AOP auto-proxy creator 注冊處理工具類。注冊了3個creator。一般BeanDefinition采用的最後一個creator:AnnotationAwareAspectJAutoProxyCreator。

private static final List<Class<?>> APC_PRIORITY_LIST = new ArrayList<>(3);
//使用數組,用來排序,最後一個的優先級最高。
	static {
		// Set up the escalation list...
		APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);
		APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);
		APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);
	}
           
@Nullable
	private static BeanDefinition registerOrEscalateApcAsRequired(
			Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {

		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
//AUTO_PROXY_CREATOR_BEAN_NAME = "org.springframework.aop.config.internalAutoProxyCreator";
		if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
			BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
//類型不比對,則根據優先級确定設定哪個creator。
			if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
				int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
				int requiredPriority = findPriorityForClass(cls);
				if (currentPriority < requiredPriority) {
					apcDefinition.setBeanClassName(cls.getName());
				}
			}
			return null;
		}

//注冊beandefinition。
		RootBeanDefinition 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;
	}
           

代理生成

AnnotationAwareAspectJAutoProxyCreator

AnnotationAwareAspectJAutoProxyCreator,其繼承關系如下:

Spring AOP源碼解析(二)—— AOP引入配置類代理生成

Aware 

可以設定ClassLoader,以及BeanFactory。

public interface BeanClassLoaderAware extends Aware {
	void setBeanClassLoader(ClassLoader classLoader);
}

public interface BeanFactoryAware extends Aware {
	void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}
           

 BeanPostProcessor 

public interface BeanPostProcessor {
	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

}


public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
	@Nullable
	default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		return null;
	}
	
	default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
		return true;
	}

	@Nullable
	default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)			throws BeansException {

		return null;
	}

	@Deprecated
	@Nullable
	default PropertyValues postProcessPropertyValues(
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {

		return pvs;
	}

}


public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
//傳回bean最終的類型。用于提前給出postProcessBeforeInstantiation生成的bean的類型
	@Nullable
	default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
		return null;
	}
//傳回bean的可選構造函數清單。用于bean初始化的時候決定調用哪一個構造函數,如果針對某個類型的bean設定了這個回調,會采用回調設定的構造函數初始化bean
	@Nullable
	default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
			throws BeansException {

		return null;
	}
//用于解決循環依賴的問題
	default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
		return bean;
	}

}
           

AopInfrastructureBean  

一個标記接口。

public interface AopInfrastructureBean {
}
           

ProxyConfig

ProxyConfig是所有産生Spring AOP代理對象的基類,它是一個資料類,主要為其AOP代理對象工廠實作類提供基本的配置屬性。

public class ProxyConfig implements Serializable {
    private static final long serialVersionUID = -8409359707199703185L;

    // 如果該值為true,則proxyFactory将會使用CGLIB對目标對象進行代理,預設值為false
    private boolean proxyTargetClass = false;

    // 标記是否對代理進行優化。啟動優化通常意味着在代理對象被建立後,增強的修改将不會生效(即增強僅對修改之後的代理對象起作用,對修改前的修改不起作用),是以預設值為false。
    private boolean optimize = false;
    
    // 該屬性用于空值生成的代理對象是否可以強制轉型為Advised,預設值為false,表示任何生成的代理對象都可以強制轉換成Advised,true是不可以,可以通過Adviced查詢代理對象的一些狀态
//[əʊˈpeɪk],不透明的;不傳熱的;遲鈍的
    boolean opaque = false;

    // 标記代理對象是否應該被aop架構通過AopContext以ThreadLocal的形式暴露出去。
    // 當一個代理對象需要調用它自己的另外一個代理方法時,這個屬性将非常有用。預設是是false,以避免不必要的攔截。
//即在方法内部互相調用時,通過((Target)AopContext.currentProxy()).innerCall(); 擷取增強後目前代理對象。
    boolean exposeProxy = false;

    // 标記該配置是否需要被當機,如果被當機,将不可以修改增強的配置。
    // 如果該值為true,那麼代理對象的生成的各項資訊配置完成,則不容許更改,如果ProxyFactory設定完畢,該值為true,則不能對Advice進行改動,可以優化代理對象生成的性能。預設情況下該值為false
    private boolean frozen = false;
...
}
           

 ProxyProcessorSupport

建立代理支援類。主要功能是:檢測代理類是否有使用者接口(包括代理類本身),如果有則proxyTargetClass為false,否則proxyTargetClass為true。即如果有接口,則使用JDK動态代理,否則使用cglib代理。

 AOP的自動代理建立器必須在所有的别的processors之後執行,以確定它可以代理到所有的小夥伴們,即使需要雙重代理的那種。是以Order設定為最低優先級。

//判斷是InitializingBean,DisposableBean這些配置回調接口	
    protected boolean isConfigurationCallbackInterface(Class<?> ifc) {
		return (InitializingBean.class == ifc || DisposableBean.class == ifc || Closeable.class == ifc ||
				AutoCloseable.class == ifc || ObjectUtils.containsElement(ifc.getInterfaces(), Aware.class));
	}
//内部語言接口
	protected boolean isInternalLanguageInterface(Class<?> ifc) {
		return (ifc.getName().equals("groovy.lang.GroovyObject") ||
				ifc.getName().endsWith(".cglib.proxy.Factory") ||
				ifc.getName().endsWith(".bytebuddy.MockAccess"));
	}
           
protected void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) {
		Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader());
		boolean hasReasonableProxyInterface = false;
		for (Class<?> ifc : targetInterfaces) {
			if (!isConfigurationCallbackInterface(ifc) && !isInternalLanguageInterface(ifc) &&
					ifc.getMethods().length > 0) {
				hasReasonableProxyInterface = true;
				break;
			}
		}
		if (hasReasonableProxyInterface) {
			// Must allow for introductions; can't just set interfaces to the target's interfaces only.
			for (Class<?> ifc : targetInterfaces) {
				proxyFactory.addInterface(ifc);
			}
		}
		else {
			proxyFactory.setProxyTargetClass(true);
		}
	}
           

AbstractAutoProxyCreator

這個類是這個繼承鍊中最核心的類,因為生成代理的邏輯封裝在這裡,它實作SmartInstantiationAwareBeanPostProcessor,在回調方法裡封裝了把bean對象替換為代理對象的邏輯,在getEarlyBeanReference,postProcessBeforeInstantiation, postProcessAfterInitialization均能産生代理,postProcessBeforeInstantiation需要在配置了TargetSourceCreator之後才能生效。getEarlyBeanReference是為了解決循環依賴重寫的,用來提前産生代理類,postProcessAfterInitialization在getEarlyBeanReference沒有生效的情況下會被調用,這兩個方法都調用了wrapIfNecessary來生成代理

屬性

/*不代理時傳回對象:null*/
	@Nullable
	protected static final Object[] DO_NOT_PROXY = null;
    /*沒有任何增強接口對象:object*/
	protected static final Object[] PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS = new Object[0];

	/** AdvisorAdapterRegistry,預設是GlobalAdvisorAdapterRegistry. */
	private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();

	/**訓示代理對象是否應該當機*/
	private boolean freezeProxy = false;

	/**攔截器名稱清單. */
	private String[] interceptorNames = new String[0];

	private boolean applyCommonInterceptorsFirst = true;

	@Nullable
	private TargetSourceCreator[] customTargetSourceCreators;

	@Nullable
	private BeanFactory beanFactory;

	private final Set<String> targetSourcedBeans = Collections.newSetFromMap(new ConcurrentHashMap<>(16));

	private final Map<Object, Object> earlyProxyReferences = new ConcurrentHashMap<>(16);

	private final Map<Object, Class<?>> proxyTypes = new ConcurrentHashMap<>(16);

	private final Map<Object, Boolean> advisedBeans = new ConcurrentHashMap<>(256);
           

Aware實作 

BeanPostProcessor實作

初始化前不做處理,初始化後如果有必要則包裝。

public Object postProcessBeforeInitialization(Object bean, String beanName) {
		return bean;
	}

@Override
	public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
		if (bean != null) {
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			if (this.earlyProxyReferences.remove(cacheKey) != bean) {
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}
           

InstantiationAwareBeanPostProcessor實作 

/**
     * 在建立Bean的流程中還沒調用構造器來執行個體化Bean的時候進行調用(執行個體化前後)
     * AOP解析切面以及事務解析事務注解都是在這裡完成的
     */
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
        //擷取BeanClass的緩存key
        Object cacheKey = getCacheKey(beanClass, beanName);

        if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
            //advisedBeans儲存了所有已經做過動态代理的Bean
            // 如果被解析過則直接傳回
            if (this.advisedBeans.containsKey(cacheKey)) {
                return null;
            }
            // 1. 判斷目前bean是否是基礎類型:是否實作了Advice,Pointcut,Advisor,AopInfrastructureBean這些接口或是否是切面(@Aspect注解)
            // 2. 判斷是不是應該跳過 (AOP解析直接解析出我們的切面資訊,
            // 而事務在這裡是不會解析的)
            if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return null;
            }
        }

        //擷取使用者自定義的targetSource, 如果存在則直接在對象執行個體化之前進行代理建立,
        // 避免了目标對象不必要的執行個體化
        TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
        //如果有自定義targetSource就要這裡建立代理對象
        //這樣做的好處是被代理的對象可以動态改變,而不是值針對一個target對象(可以對對象池中對象進行代理,可以每次建立代理都建立新對象
        if (targetSource != null) {
            if (StringUtils.hasLength(beanName)) {
                this.targetSourcedBeans.add(beanName);
            }
            //擷取Advisors, 這個是交給子類實作的
            Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
            Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
            this.proxyTypes.put(cacheKey, proxy.getClass());
            //傳回代理的對象
            return proxy;
        }

        return null;
    }
}
           
@Override
	public boolean postProcessAfterInstantiation(Object bean, String beanName) {
		return true;
	}

	@Override
	public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
		return pvs;
	}
           

SmartInstantiationAwareBeanPostProcessor實作 

wrapIfNecessary

wrapIfNecessary首先會通過getAdvicesAndAdvisorsForBean得到攔截器集合,這個會交給子類實作,子類可以設計不同的政策來擷取攔截器集合,如果getAdvicesAndAdvisorsForBean傳回的集合不為空,就調用createProxy生成代理

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//已經有bean,直接傳回。
		if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
			return bean;
		}
//沒有advice,直接傳回bean。
		if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
			return bean;
		}
//不需要處理的,直接傳回。
		if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return bean;
		}

		// 如果有advice,則進行代理。由子類實作
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		if (specificInterceptors != DO_NOT_PROXY) {
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
			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;
	}
           

createProxy

使用了ProxyFactory的程式設計式Aop生成代理。

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);
        //JDK還是cglib判斷。
		if (!proxyFactory.isProxyTargetClass()) {
			if (shouldProxyTargetClass(beanClass, beanName)) {
				proxyFactory.setProxyTargetClass(true);
			}
			else {
				evaluateProxyInterfaces(beanClass, proxyFactory);
			}
		}
        //構造Advisor。
		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
		proxyFactory.addAdvisors(advisors);
		proxyFactory.setTargetSource(targetSource);
		customizeProxyFactory(proxyFactory);

		proxyFactory.setFrozen(this.freezeProxy);
		if (advisorsPreFiltered()) {
			proxyFactory.setPreFiltered(true);
		}
        //傳回代理對象。
		return proxyFactory.getProxy(getProxyClassLoader());
	}
           

buildAdvisors

此函數把攔截器包裝成Advisor,是通過AdvisorAdapterRegistry類來完成。

protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
		// Handle prototypes correctly...
        //指定攔截器name 處理成Advisor。
		Advisor[] commonInterceptors = resolveInterceptorNames();
        //所有攔截器
		List<Object> allInterceptors = new ArrayList<>();
		if (specificInterceptors != null) {
            //
			allInterceptors.addAll(Arrays.asList(specificInterceptors));
			if (commonInterceptors.length > 0) {
				if (this.applyCommonInterceptorsFirst) {
					allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
				}
				else {
					allInterceptors.addAll(Arrays.asList(commonInterceptors));
				}
			}
		}
		if (logger.isTraceEnabled()) {
			int nrOfCommonInterceptors = commonInterceptors.length;
			int nrOfSpecificInterceptors = (specificInterceptors != null ? specificInterceptors.length : 0);
			logger.trace("Creating implicit proxy for bean '" + beanName + "' with " + nrOfCommonInterceptors +
					" common interceptors and " + nrOfSpecificInterceptors + " specific interceptors");
		}
        //Advisor:攔截器包裝成Advisor。
		Advisor[] advisors = new Advisor[allInterceptors.size()];
		for (int i = 0; i < allInterceptors.size(); i++) {
			advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
		}
		return advisors;
	}
           

AdvisorAdapterRegistry

AdvisorAdapterRegistry 實作攔截器包裝成Advisor功能,以及注冊AdvisorAdapter 。AdvisorAdapterRegistry通過GlobalAdvisorAdapterRegistry擷取單例:DefaultAdvisorAdapterRegistry執行個體。

public interface AdvisorAdapterRegistry {

	Advisor wrap(Object advice) throws UnknownAdviceTypeException;
	MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException;
	void registerAdvisorAdapter(AdvisorAdapter adapter);

}
           
private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();
           

DefaultAdvisorAdapterRegistry

DefaultAdvisorAdapterRegistry預設注冊3個AdvisorAdapter。wrap方法把攔截器包裝成DefaultPointcutAdvisor。DefaultPointcutAdvisor比對任何方法。

public DefaultAdvisorAdapterRegistry() {
		registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
		registerAdvisorAdapter(new AfterReturningAdviceAdapter());
		registerAdvisorAdapter(new ThrowsAdviceAdapter());
	}
           

ProxyFactory

ProxyFactory是真正建立代理對象的工廠。内容太多,放後面再分析。

AbstractAdvisorAutoProxyCreator

AbstractAdivisorAutoProxyCreator主要實作了AbstractAutoProxyCreator提供的擴充點方法getAdvicesAndAdvisorsForBean,用來設定攔截器集合。通過BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans()擷取Advisors。

1、findCandidateAdvisors()方法先擷取注冊到Spring容器中的Advisor。

2、findAdvisorsThatCanApply()過濾Advisor,Advisor(切點)包含了Pointcut(切點)和Advice(增強),findAdvisorsThatCanApply方法的過濾就是利用Advisor中Pointcut比對Class或Method來達到過濾的目的。

3、extendAdvisors()擴充Adviors,由子類實作。

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

		List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
		if (advisors.isEmpty()) {
			return DO_NOT_PROXY;
		}
		return advisors.toArray();
	}
           
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
//1.
		List<Advisor> candidateAdvisors = findCandidateAdvisors();
//2.
		List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
//3.
		extendAdvisors(eligibleAdvisors);
		if (!eligibleAdvisors.isEmpty()) {
			eligibleAdvisors = sortAdvisors(eligibleAdvisors);
		}
		return eligibleAdvisors;
	}
           
protected List<Advisor> findCandidateAdvisors() {
		Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
		return this.advisorRetrievalHelper.findAdvisorBeans();
	}
           

BeanFactoryAdvisorRetrievalHelper

從容器中擷取

Spring

Advisor

bean

 : 也就是實作了接口

org.springframework.aop.Advisor

bean

public List<Advisor> findAdvisorBeans() {
        //擷取Advisor的name
		String[] advisorNames = this.cachedAdvisorBeanNames;
		if (advisorNames == null) {
            //查找Advisor.class類型的bean的name。不要在此處初始化FactoryBeans,讓auto-proxy creator處理。
			advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
					this.beanFactory, Advisor.class, true, false);
			this.cachedAdvisorBeanNames = advisorNames;
		}
		if (advisorNames.length == 0) {
			return new ArrayList<>();
		}

		List<Advisor> advisors = new ArrayList<>();
		for (String name : advisorNames) {
			if (isEligibleBean(name)) {
				if (this.beanFactory.isCurrentlyInCreation(name)) {
					if (logger.isTraceEnabled()) {
						logger.trace("Skipping currently created advisor '" + name + "'");
					}
				}
				else {
					try {
                    //擷取Advisor
						advisors.add(this.beanFactory.getBean(name, Advisor.class));
					}
					catch (BeanCreationException ex) {
						... ...
					}
				}
			}
		}
		return advisors;
	}
           

AspectJAwareAdvisorAutoProxyCreator

Aspectj的實作方式,也是Spring Aop中最常用的實作方式,如果用注解方式,則用其子類

AnnotationAwareAspectJAutoProxyCreator

重寫了父類的extendAdvisors()。作用就是在所有的advisors節點最前面插入一個Advisor(有advisors節點前提下,DefaultPointcutAdvisor),此Advisor比較特殊它的Pointcut是全類型比對的(比對所有Class和Method),它主要功能是在于它的Advice(增強),它的Advice實作是ExposeInvocationInterceptor類,看類的名稱就知道,對外暴露的類,就是所有Advice調用鍊的第一環,ExposeInvocationInterceptor作用就是将調用資訊存在ThreadLocal實作的上下文資訊裡,供調用鍊後續的Advice擷取使用。

 extendAdvisors

@Override
	protected void extendAdvisors(List<Advisor> candidateAdvisors) {
		AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(candidateAdvisors);
	}
           

AspectJProxyUtils 

AspectJ代理工具類。

private static boolean isAspectJAdvice(Advisor advisor) {
		return (advisor instanceof InstantiationModelAwarePointcutAdvisor ||
				advisor.getAdvice() instanceof AbstractAspectJAdvice ||
				(advisor instanceof PointcutAdvisor &&
						((PointcutAdvisor) advisor).getPointcut() instanceof AspectJExpressionPointcut));
	}
           
public static boolean makeAdvisorChainAspectJCapableIfNecessary(List<Advisor> advisors) {
		// Don't add advisors to an empty list; may indicate that proxying is just not required
		if (!advisors.isEmpty()) {
			boolean foundAspectJAdvice = false;
			for (Advisor advisor : advisors) {
				// Be careful not to get the Advice without a guard, as this might eagerly
				// instantiate a non-singleton AspectJ aspect...
				if (isAspectJAdvice(advisor)) {
					foundAspectJAdvice = true;
					break;
				}
			}
			if (foundAspectJAdvice && !advisors.contains(ExposeInvocationInterceptor.ADVISOR)) {
				advisors.add(0, ExposeInvocationInterceptor.ADVISOR);
				return true;
			}
		}
		return false;
	}
           
public static final Advisor ADVISOR = new DefaultPointcutAdvisor(INSTANCE) {
		@Override
		public String toString() {
			return ExposeInvocationInterceptor.class.getName() +".ADVISOR";
		}
	};
           

AnnotationAwareAspectJAutoProxyCreator

AnnotationAwareAspectJAutoProxyCreator

:目前最常用的AOP使用方式。spring aop 開啟注解方式之後,該類會掃描所有

@Aspect()

注釋的類,生成對應的

adviosr

。目前

SpringBoot

架構中預設支援的方式,自動配置。

通過BeanFactoryAspectJAdvisorsBuilder建立AspectJ Advisor。

覆寫父類:findCandidateAdvisors

@Override
	protected List<Advisor> findCandidateAdvisors() {
		List<Advisor> advisors = super.findCandidateAdvisors();
		// 利用了aspectj來解析注解了@Aspect
		if (this.aspectJAdvisorsBuilder != null) {
			advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
		}
		return advisors;
	}
           

BeanFactoryAspectJAdvisorsBuilder

BeanFactoryAspectJAdvisorsBuilder

是一個

Spring AOP

内部工具類,該工具類用來從

bean

容器,也就是

BeanFactory

中擷取所有使用了

@AspectJ

注解的

bean

,最終用于自動代理機制(

auto-proxying

)。

     buildAspectJAdvisors() 方法将所有 @AspectJ bean advice 方法包裝成Spring Advisor清單傳回:

1. 從容器中找到所有@AspectJ注解的bean;

2. 将找到的每個@AspectJ bean的每個advice方法封裝成一個Spring Advisor;

3. 緩存找到的Spring Advisor;

4. 将上述找到的所有Spring Advisor組織成一個清單傳回

public List<Advisor> buildAspectJAdvisors() {
		List<String> aspectNames = this.aspectBeanNames;

		if (aspectNames == null) {
        //線程安全處理。二次check 方法
			synchronized (this) {
				aspectNames = this.aspectBeanNames;
				if (aspectNames == null) {
					List<Advisor> advisors = new ArrayList<>();
					aspectNames = new ArrayList<>();
					// 擷取所有類型為Object的bean的名稱,基本上也就是說所有的bean的名稱了
					// includeNonSingletons:true=>包含單例,非單例bean
					// allowEagerInit:false=>不要初始化lazy-init singletons和FactoryBean建立的bean
					String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
							this.beanFactory, Object.class, true, false);
					for (String beanName : beanNames) {					
						if (!isEligibleBean(beanName)) {
							// 本執行個體自己提供的篩查條件,預設實作總是傳回true,
							// 子類可以覆寫該方法提供自己的實作
							continue;
						}

						Class<?> beanType = this.beanFactory.getType(beanName);
						if (beanType == null) {
							continue;
						}
						// 檢測該bean是否使用了注解@AspectJ
						if (this.advisorFactory.isAspect(beanType)) {
							// 檢測到了一個使用注解@AspectJ的bean
							aspectNames.add(beanName);
                            
							AspectMetadata amd = new AspectMetadata(beanType, beanName);
                            // 切面的屬性為單例模式
							if (amd.getAjType().getPerClause().getKind() == 
								PerClauseKind.SINGLETON) {
								MetadataAwareAspectInstanceFactory factory =
										new BeanFactoryAspectInstanceFactory(this.beanFactory,
											 beanName);
								// 從@AspectJ注解的類,也就是AspectJ切面類中分析
								// 其advice方法,每個構造成一個Spring Advisor,
								// pointcut 資訊 和 advice 資訊已經包含在相應的Advisor
								// 對象中
								List<Advisor> classAdvisors = 
									this.advisorFactory.getAdvisors(factory);
                             // 單例模式,隻需要将生成的Advisor添加到緩存
								if (this.beanFactory.isSingleton(beanName)) {
									this.advisorsCache.put(beanName, classAdvisors);
								}
                                // 多執行個體模式,需要儲存工廠類,便于下一次再次生成Advisor執行個體。
								else {
									this.aspectFactoryCache.put(beanName, factory);
								}
								advisors.addAll(classAdvisors);
							}
							else {
								// 非單例模式,每個執行個體處理一次。
								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;
	}
           

AspectJAdvisorFactory 

為AspectJ的切面構造Advisor,也就是說處理@Aspect修飾的類。構造器預設使用的是ReflectiveAspectJAdvisorFactory。

public interface AspectJAdvisorFactory {
	boolean isAspect(Class<?> clazz);
	void validate(Class<?> aspectClass) throws AopConfigException;
    
	List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory);
	@Nullable
	Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
			int declarationOrder, String aspectName);
	@Nullable
	Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
			MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName);
}
           

DefaultAdvisorAutoProxyCreator

擴充isEligibleAdvisorBean,通過配置的prefix來過濾adivisor bean。

@Override
	protected boolean isEligibleAdvisorBean(String beanName) {
		if (!isUsePrefix()) {
			return true;
		}
		String prefix = getAdvisorBeanNamePrefix();
		return (prefix != null && beanName.startsWith(prefix));
	}
           

InfrastructureAdvisorAutoProxyCreator

擴充isEligibleAdvisorBean,這個過濾條件是,隻選擇架構級别(beanDefinition的role為ROLE_INFRASTRUCTURE)的Adivisor來進行對符合條件的對象進行織入,生成代理。

@Override
	protected boolean isEligibleAdvisorBean(String beanName) {
		return (this.beanFactory != null && this.beanFactory.containsBeanDefinition(beanName) &&
				this.beanFactory.getBeanDefinition(beanName).getRole() == BeanDefinition.ROLE_INFRASTRUCTURE);
	}