javascript
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 {@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { //1AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry); //2AnnotationAttributes 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);} @Nullableprivate 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,其繼承關系如下:
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 {@Nullabledefault Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}@Nullabledefault Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}}public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {@Nullabledefault Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {return null;}default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {return true;}@Nullabledefault PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {return null;}@Deprecated@Nullabledefault PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {return pvs;}}public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor { //返回bean最終的類型。用于提前給出postProcessBeforeInstantiation生成的bean的類型@Nullabledefault Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {return null;} //返回bean的可選構造函數列表。用于bean初始化的時候決定調用哪一個構造函數,如果針對某個類型的bean設置了這個回調,會采用回調設置的構造函數初始化bean@Nullabledefault 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對目標對象進行代理,默認值為falseprivate 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進行改動,可以優化代理對象生成的性能。默認情況下該值為falseprivate 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*/@Nullableprotected 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;@Nullableprivate TargetSourceCreator[] customTargetSourceCreators;@Nullableprivate 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;}@Overridepublic 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解析切面以及事務解析事務注解都是在這里完成的*/@Overridepublic Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {//獲取BeanClass的緩存keyObject 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;} } @Overridepublic boolean postProcessAfterInstantiation(Object bean, String beanName) {return true;}@Overridepublic 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,由子類實現。
@Nullableprotected 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的nameString[] 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 {//獲取Advisoradvisors.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
@Overrideprotected 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 requiredif (!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) {@Overridepublic String toString() {return ExposeInvocationInterceptor.class.getName() +".ADVISOR";}};AnnotationAwareAspectJAutoProxyCreator
AnnotationAwareAspectJAutoProxyCreator:目前最常用的AOP使用方式。spring aop 開啟注解方式之后,該類會掃描所有@Aspect()注釋的類,生成對應的adviosr。目前SpringBoot框架中默認支持的方式,自動配置。
通過BeanFactoryAspectJAdvisorsBuilder創建AspectJ Advisor。
覆蓋父類:findCandidateAdvisors
@Overrideprotected List<Advisor> findCandidateAdvisors() {List<Advisor> advisors = super.findCandidateAdvisors();// 利用了aspectj來解析注解了@Aspectif (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組織成一個列表返回
AspectJAdvisorFactory?
為AspectJ的切面構造Advisor,也就是說處理@Aspect修飾的類。構造器默認使用的是ReflectiveAspectJAdvisorFactory。
public interface AspectJAdvisorFactory {boolean isAspect(Class<?> clazz);void validate(Class<?> aspectClass) throws AopConfigException;List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory);@NullableAdvisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,int declarationOrder, String aspectName);@NullableAdvice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName); }DefaultAdvisorAutoProxyCreator
擴展isEligibleAdvisorBean,通過配置的prefix來過濾adivisor bean。
@Overrideprotected boolean isEligibleAdvisorBean(String beanName) {if (!isUsePrefix()) {return true;}String prefix = getAdvisorBeanNamePrefix();return (prefix != null && beanName.startsWith(prefix));}InfrastructureAdvisorAutoProxyCreator
擴展isEligibleAdvisorBean,這個過濾條件是,只選擇框架級別(beanDefinition的role為ROLE_INFRASTRUCTURE)的Adivisor來進行對符合條件的對象進行織入,生成代理。
@Overrideprotected boolean isEligibleAdvisorBean(String beanName) {return (this.beanFactory != null && this.beanFactory.containsBeanDefinition(beanName) &&this.beanFactory.getBeanDefinition(beanName).getRole() == BeanDefinition.ROLE_INFRASTRUCTURE);}?
總結
以上是生活随笔為你收集整理的Spring AOP源码解析(二)—— AOP引入的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring的@Configuratio
- 下一篇: Spring AOP源码解析(三)——