Springboot源碼分析之EnableAspectJAutoProxy

摘要:

Spring Framwork的兩大核心技術(shù)就是IOCAOP,AOPSpring的產(chǎn)品線中有著大量的應(yīng)用。如果說反射是你通向高級的基礎(chǔ),那么代理就是你站穩(wěn)高級的底氣。AOP的本質(zhì)也就是大家所熟悉的CGLIB動態(tài)代理技術(shù),在日常工作中想必或多或少都用過但是它背后的秘密值得我們?nèi)ド钏?。本文主要?code>Spring AOP運行過程上,結(jié)合一定的源碼整體上介紹Spring AOP的一個運行過程。知其然,知其所以然,才能更好的駕馭這門核心技術(shù)。

    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import({AspectJAutoProxyRegistrar.class})
    public @interface EnableAspectJAutoProxy {
        //表明該類采用CGLIB代理還是使用JDK的動態(tài)代理
        boolean proxyTargetClass() default false;
         /**
         * @since 4.3.1 代理的暴露方式:解決內(nèi)部調(diào)用不能使用代理的場景  默認為false表示不處理
         * true:這個代理就可以通過AopContext.currentProxy()獲得這個代理對象的一個副本(ThreadLocal里面),從而我們可以很方便得在Spring框架上下文中拿到當(dāng)前代理對象(處理事務(wù)時很方便)
         * 必須為true才能調(diào)用AopContext得方法,否則報錯:Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available.
         */
        boolean exposeProxy() default false;
    }

所有的EnableXXX驅(qū)動技術(shù)都得看他的@Import,所以上面最重要的是這一句@Import(AspectJAutoProxyRegistrar.class),下面看看它

    class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
        AspectJAutoProxyRegistrar() {
        }
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
            //注冊了一個基于注解的自動代理創(chuàng)建器   AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
            AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
            if (enableAspectJAutoProxy != null) {
                  //表示強制指定了要使用CGLIB
                if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
                    AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
                }
              //強制暴露Bean的代理對象到AopContext
                if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
                    AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
                }
            }
        }
    }

AspectJAutoProxyRegistrar是一個項容器注冊自動代理創(chuàng)建器

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

說明spring容器的注解代理創(chuàng)建器就是AnnotationAwareAspectJAutoProxyCreator

    @Nullable
        private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
            Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
          //這里如果我們自己定義了這樣一個自動代理創(chuàng)建器就是用我們自定義的
            if (registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) {
                BeanDefinition apcDefinition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
                if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
                    int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
                  /** 
                   *用戶注冊的創(chuàng)建器,必須是InfrastructureAdvisorAutoProxyCreator
                   *AspectJAwareAdvisorAutoProxyCreator,AnnotationAwareAspectJAutoProxyCreator之一
                  */
                    int requiredPriority = findPriorityForClass(cls);
                    if (currentPriority < requiredPriority) {
                        apcDefinition.setBeanClassName(cls.getName());
                    }
                }
                return null;
            } 
          //若用戶自己沒有定義,那就用默認的AnnotationAwareAspectJAutoProxyCreator
          RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
              beanDefinition.setSource(source);
          //此處注意,增加了一個屬性:最高優(yōu)先級執(zhí)行,后面會和@Async注解一起使用的時候起關(guān)鍵作用
            beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
            beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
            registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
            return beanDefinition;
        }

我們就成功的注入了一個BeanAnnotationAwareAspectJAutoProxyCreator 基于注解的自動代理創(chuàng)建器

Spring中自動創(chuàng)建代理器

file

由此可見,Spring使用BeanPostProcessor讓自動生成代理?;?code>BeanPostProcessor的自動代理創(chuàng)建器的實現(xiàn)類,將根據(jù)一些規(guī)則在容器實例化Bean時為匹配的Bean生成代理實例。

AbstractAutoProxyCreator是對自動代理創(chuàng)建器的一個抽象實現(xiàn)。最重要的是,它實現(xiàn)了SmartInstantiationAwareBeanPostProcessor接口,因此會介入到Spring IoC容器Bean實例化的過程。

SmartInstantiationAwareBeanPostProcessor繼承InstantiationAwareBeanPostProcessor所以它最主要的 職責(zé)是在bean的初始化前,先會執(zhí)行所有的InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation,誰第一個返回了不為nullBean,后面就都不會執(zhí)行了 。然后會再執(zhí)行BeanPostProcessor#postProcessAfterInitialization

    protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
            Object exposedObject = bean;
            if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                for (BeanPostProcessor bp : getBeanPostProcessors()) {
                    if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                        SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
                        exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
                    }
                }
            }
            return exposedObject;
        }

說明:這個方法是spring的三級緩存中的其中一環(huán),當(dāng)你調(diào)用Object earlySingletonReference = getSingleton(beanName, false);時候就會觸發(fā),其實還有一個地方exposedObject = initializeBean(beanName, exposedObject, mbd);也會觸發(fā)導(dǎo)致返回一個代理對象。

    protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                    invokeAwareMethods(beanName, bean);
                    return null;
                }, getAccessControlContext());
            }
            else {
                invokeAwareMethods(beanName, bean);
            }
            Object wrappedBean = bean;
            if (mbd == null || !mbd.isSynthetic()) {
                wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
            }
            try {
                invokeInitMethods(beanName, wrappedBean, mbd);
            }
            catch (Throwable ex) {
                throw new BeanCreationException(
                        (mbd != null ? mbd.getResourceDescription() : null),
                        beanName, "Invocation of init method failed", ex);
            }
            if (mbd == null || !mbd.isSynthetic()) {
                wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
            }
            return wrappedBean;
        }

強調(diào): 這2個地方雖然都有后置增強的作用,但是@Async所使用的AsyncAnnotationBeanPostProcessor不是SmartInstantiationAwareBeanPostProcessor的實現(xiàn)類,所以此處會導(dǎo)致@Transactional@Async處理循環(huán)依賴時候的不一致性。對于循環(huán)依賴后續(xù)會有單獨章節(jié)進行分享。

AbstractAdvisorAutoProxyCreator

如何創(chuàng)建代理對象后續(xù)文章在進行分析。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容