最近,很多小夥伴在催更【Spring註解驅動開發】專題,好吧,【Spring註解驅動開發】專題確實有很長時間沒更新了。那咱們從今天開始更新【Spring註解驅動開發】專題,一樣的,咱們仍是以源碼解析爲主。文章已同步收錄到:https://github.com/sunshinelyz/technology-binghe 和 https://gitee.com/binghe001/technology-binghe 。若是文件對你有點幫助,別忘記給個Star哦!java
關注【冰河技術】微信公衆號,回覆「Spring註解」領取工程源碼。git
咱們先來看下AnnotationAwareAspectJAutoProxyCreator類的結構圖。程序員
上圖中一些 類/接口 的介紹:github
AspectJAwareAdvisorAutoProxyCreator : 公開了AspectJ的調用上下文,並弄清楚來自同一切面的多個Advisor在AspectJ中的優先級規則。面試
AbstractAdvisorAutoProxyCreator : 通用自動代理建立器,它基於檢測到的每一個顧問程序爲特定bean構建AOP代理。spring
AbstractAutoProxyCreator : 擴展了 ProxyProcessorSupport,實現了SmartInstantiationAwareBeanPostProcessor、BeanFactoryAware 接口,是BeanPostProcessor 實現,該實現使用AOP代理包裝每一個合格的bean,並在調用bean自己以前委派給指定的攔截器。緩存
BeanFactoryAware : 實現了該接口的Bean能夠知道它屬於那個 BeanFactory,Bean能夠經過Spring容器查找它的協同者(依賴查找),但大多數的Bean是經過構造器參數和Bean方法(依賴注入)來獲取它的協同者。微信
BeanPostProcessor :工廠鉤子,容許自定義修改新的bean實例。例如,檢查標記接口或使用代理包裝bean。若是咱們須要在Spring容器中完成Bean的實例化,配置和其初始化先後添加一些本身的邏輯處理,咱們就能夠定義一個或多個BeanPostProcessor接口的實現,而後註冊到容器中。ide
InstantiationAwareBeanPostProcessor : BeanPostProcessor 的子接口,它添加了實例化以前的回調,以及實例化以後但設置了顯式屬性或自動裝配以前的回調。它內部提供了3個方法,再加上BeanPostProcessor接口內部的2個方法,實現這個接口須要實現5個方法。InstantiationAwareBeanPostProcessor 接口的主要做用在於目標對象的實例化過程當中須要處理的事情,包括實例化對象的先後過程以及實例的屬性設置。post
SmartInstantiationAwareBeanPostProcessor : InstantiationAwareBeanPostProcessor 接口的擴展,多出了3個方法,添加了用於預測已處理bean的最終類型的回調,再加上父接口的5個方法,因此實現這個接口須要實現8個方法,主要做用也是在於目標對象的實例化過程當中須要處理的事情。
總之:AspectJAwareAdvisorAutoProxyCreator爲 AspectJ 切面類建立自動代理。
BeanPostProcessor 接口中的兩個方法 postProcessBeforeInitialization 和 postProcessAfterInitialization,做用是對Bean初始化先後添加一些本身的邏輯。
@Nullable default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } @Nullable default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; }
InstantiationAwareBeanPostProcessor 是 BeanPostProcessor 的子接口,它額外增長了3個新的方法:postProcessBeforeInstantiation( 目標對象被實例化以前調用的方法,能夠返回目標實例的一個代理用來代替目標實例 )、postProcessAfterInstantiation(該方法在Bean實例化以後執行,返回false,會忽略屬性值的設置;若是返回true,會按照正常流程設置屬性值) 和 postProcessPropertyValues(對屬性值進行修改,將來版本將會刪除)
@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 postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { return pvs; }
SmartInstantiationAwareBeanPostProcessor接口繼承InstantiationAwareBeanPostProcessor接口,裏面定義了3個方法:predictBeanType(預測Bean的類型)、determineCandidateConstructors(選擇合適的構造器)、getEarlyBeanReference(解決循環引用問題)。
@Nullable default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException { return null; } @Nullable default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException { return null; } default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException { return bean; }
AbstractAutoProxyCreator 是AOP的一個核心類,它實現了SmartInstantiationAwareBeanPostProcessor、BeanFactoryAware 接口,實現了代理建立的邏輯,使用AOP代理包裝每一個合格的bean,並在調用bean自己以前委派給指定的攔截器。
AbstractAdvisorAutoProxyCreator 通用自動代理建立器,它基於檢測每一個bean的加強器,爲特殊的bean構建AOP代理。子類能夠重寫此findCandidateAdvisors()方法,以返回適用於任何對象的advisor的自定義列表,子類還能夠重寫繼承的AbstractAutoProxyCreator.shouldSkip()方法,以將某些對象排除在自動代理以外。
protected List<Advisor> findCandidateAdvisors() { Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available"); return this.advisorRetrievalHelper.findAdvisorBeans(); }
AspectJAwareAdvisorAutoProxyCreator 擴展 AbstractAdvisorAutoProxyCreator,公開了AspectJ的調用上下文,並在多個加強器來自同一切面時搞清楚AspectJ的建議優先級順序。按AspectJ優先級排序其他部分:
@Override @SuppressWarnings("unchecked") protected List<Advisor> sortAdvisors(List<Advisor> advisors) { List<PartiallyComparableAdvisorHolder> partiallyComparableAdvisors = new ArrayList<>(advisors.size()); for (Advisor element : advisors) { partiallyComparableAdvisors.add( new PartiallyComparableAdvisorHolder(element, DEFAULT_PRECEDENCE_COMPARATOR)); } List<PartiallyComparableAdvisorHolder> sorted = PartialOrder.sort(partiallyComparableAdvisors); if (sorted != null) { List<Advisor> result = new ArrayList<>(advisors.size()); for (PartiallyComparableAdvisorHolder pcAdvisor : sorted) { result.add(pcAdvisor.getAdvisor()); } return result; } else { return super.sortAdvisors(advisors); } }
在加強鏈頭部增長一個ExposeInvocationInterceptor,使用AspectJ表達式切入點和使用AspectJ樣式的advisor時,須要這些附加advisor。
protected void extendAdvisors(List<Advisor> candidateAdvisors) { AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(candidateAdvisors); }
若是此後處理器不該該考慮將給定的bean用於自動代理,子類應重寫此方法以返回true
@Override protected boolean shouldSkip(Class<?> beanClass, String beanName) { // TODO: Consider optimization by caching the list of the aspect names List<Advisor> candidateAdvisors = findCandidateAdvisors(); for (Advisor advisor : candidateAdvisors) { if (advisor instanceof AspectJPointcutAdvisor && ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) { return true; } } return super.shouldSkip(beanClass, beanName); }
AspectJAwareAdvisorAutoProxyCreator 還有一個子類叫 AnnotationAwareAspectJAutoProxyCreator,子類AnnotationAwareAspectJAutoProxyCreator是用於處理當前應用程序上下文中的全部AspectJ註釋方面以及Spring Advisor。若是Spring AOP的基於代理的模型可以應用任何AspectJ註釋的類,它們的advisor將被自動識別,這涵蓋了方法執行鏈接點,Spring Advisor的處理遵循AbstractAdvisorAutoProxyCreator中創建的規則。
從使用<aop:xxx>標籤來自動生成代理的話,先看看AopNamespaceHandler,使用<aop:config>標籤則使用 ConfigBeanDefinitionParser 解析,使用了<aop:aspectj-autoproxy>標籤則使用 AspectJAutoProxyBeanDefinitionParser 解析,依次類推。
@Override public void init() { // In 2.0 XSD as well as in 2.1 XSD. registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser()); registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser()); registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator()); // Only in 2.0 XSD: moved to context namespace as of 2.1 registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser()); }
ConfigBeanDefinitionParser.java
@Override @Nullable public BeanDefinition parse(Element element, ParserContext parserContext) { CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element)); parserContext.pushContainingComponent(compositeDef); configureAutoProxyCreator(parserContext, element); // 註冊AspectJAwareAdvisorAutoProxyCreator List<Element> childElts = DomUtils.getChildElements(element); for (Element elt: childElts) { String localName = parserContext.getDelegate().getLocalName(elt); if (POINTCUT.equals(localName)) { parsePointcut(elt, parserContext); } else if (ADVISOR.equals(localName)) { parseAdvisor(elt, parserContext); } else if (ASPECT.equals(localName)) { parseAspect(elt, parserContext); } } parserContext.popAndRegisterContainingComponent(); return null; } private void configureAutoProxyCreator(ParserContext parserContext, Element element) { AopNamespaceUtils.registerAspectJAutoProxyCreatorIfNecessary(parserContext, element); }
AopConfigUtils.java
@Override @Nullable public BeanDefinition parse(Element element, ParserContext parserContext) { CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element)); parserContext.pushContainingComponent(compositeDef); configureAutoProxyCreator(parserContext, element); // 註冊AspectJAwareAdvisorAutoProxyCreator List<Element> childElts = DomUtils.getChildElements(element); for (Element elt: childElts) { String localName = parserContext.getDelegate().getLocalName(elt); if (POINTCUT.equals(localName)) { parsePointcut(elt, parserContext); } else if (ADVISOR.equals(localName)) { parseAdvisor(elt, parserContext); } else if (ASPECT.equals(localName)) { parseAspect(elt, parserContext); } } parserContext.popAndRegisterContainingComponent(); return null; } private void configureAutoProxyCreator(ParserContext parserContext, Element element) { AopNamespaceUtils.registerAspectJAutoProxyCreatorIfNecessary(parserContext, element); }
AopConfigUtils.java
public static void registerAspectJAutoProxyCreatorIfNecessary( ParserContext parserContext, Element sourceElement) { // 在這裏註冊的是AspectJAwareAdvisorAutoProxyCreator BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAutoProxyCreatorIfNecessary( parserContext.getRegistry(), parserContext.extractSource(sourceElement)); useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement); registerComponentIfNecessary(beanDefinition, parserContext); // 註冊組件 }
@Nullable public static BeanDefinition registerAspectJAutoProxyCreatorIfNecessary( BeanDefinitionRegistry registry, @Nullable Object source) { return registerOrEscalateApcAsRequired(AspectJAwareAdvisorAutoProxyCreator.class, registry, source); }
AspectJAwareAdvisorAutoProxyCreator 實現了 BeanPostProcessor 等上面介紹的接口,主要做用於Bean初始化先後,實例化先後,全部的Bean都被做用到。InstantiationAwareBeanPostProcessor 是 BeanPostProcessor的子接口,但它的調用時間點發生在Bean實例化前,在真正調用doCreateBean()建立bean實例以前執行postProcessBeforeInstantiation()。
AbstractAutoProxyCreator.java
@Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { Object cacheKey = getCacheKey(beanClass, beanName); // 獲得一個緩存的惟一key(根據beanClass和beanName生成惟一key) // 若是當前targetSourcedBeans(經過自定義TargetSourceCreator建立的TargetSource)不包含cacheKey if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) { if (this.advisedBeans.containsKey(cacheKey)) { //advisedBeans(已經被加強的Bean,即AOP代理對象)中包含當前cacheKey,返回null,即走Spring默認流程 return null; } if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {// 若是是基礎設施類(如Advisor、Advice、AopInfrastructureBean的實現)不進行處理;(略) this.advisedBeans.put(cacheKey, Boolean.FALSE); return null; } } // 若是有自定義的TargetSource,在此處建立代理 // 禁止目標Bean的沒必要要的默認實例化: // TargetSource將以自定義方式處理目標實例。 TargetSource targetSource = getCustomTargetSource(beanClass, beanName); if (targetSource != null) { if (StringUtils.hasLength(beanName)) { this.targetSourcedBeans.add(beanName); } Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource); Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } return null; }
經過 AbstractAutoProxyCreator 中的 postProcessAfterInitialization() 建立AOP代理。
@Override public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (!this.earlyProxyReferences.contains(cacheKey)) { // 若是以前調用過getEarlyBeanReference獲取包裝目標對象到AOP代理對象(若是須要),則再也不執行 return wrapIfNecessary(bean, beanName, cacheKey); // 包裝目標對象到AOP代理對象(若是須要) } } return bean; } protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { // 經過TargetSourceCreator進行自定義TargetSource不須要包裝 return bean; } if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { // 不該該被加強對象不須要包裝 return bean; } if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { // 基礎設施或應該skip的不須要保證 this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } // 若是有advise則建立代理。 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; }
好了,今天就到這兒吧,我是冰河,咱們下期見~~
微信搜一搜【冰河技術】微信公衆號,關注這個有深度的程序員,天天閱讀超硬核技術乾貨,公衆號內回覆【PDF】有我準備的一線大廠面試資料和我原創的超硬核PDF技術文檔,以及我爲你們精心準備的多套簡歷模板(不斷更新中),但願你們都能找到心儀的工做,學習是一條時而鬱鬱寡歡,時而開懷大笑的路,加油。若是你經過努力成功進入到了心儀的公司,必定不要懈怠放鬆,職場成長和新技術學習同樣,不進則退。若是有幸咱們江湖再見!
另外,我開源的各個PDF,後續我都會持續更新和維護,感謝你們長期以來對冰河的支持!!