Spring Boot源碼-Spring AOP創(chuàng)建代理的入口


1 概述
2 Spring Boot自動(dòng)配置下AnnotationAwareAspectJAutoProxyCreator的注冊(cè)

1 概述

了解過(guò)Spring源碼的都知道Spring是通過(guò)動(dòng)態(tài)代理實(shí)現(xiàn)AOP的,Spring中實(shí)現(xiàn)動(dòng)態(tài)代理有兩種方式,分別為JDK原生動(dòng)態(tài)代理和CGLIB,這里不對(duì)動(dòng)態(tài)代理的具體實(shí)現(xiàn)進(jìn)行介紹,主要介紹Spring實(shí)現(xiàn)動(dòng)態(tài)代理的相關(guān)入口。

在進(jìn)行接下來(lái)的介紹之前,我們要先看下Spring在創(chuàng)建一個(gè)Bean的實(shí)例之后時(shí)如何對(duì)Bean進(jìn)行初始化的,AbstractAutowireCapableBeanFactory在實(shí)例化一個(gè)Bean之后,會(huì)分別調(diào)用populateBeaninitializeBean進(jìn)行Bean的依賴(lài)注入和初始化,這里我們僅僅看initializeBean的實(shí)現(xiàn):

//AbstractAutowireCapableBeanFactory
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
    //如何Bean實(shí)現(xiàn)了一些Aware接口,則調(diào)用相應(yīng)的方法,比如
    //BeanFactoryAware的setBeanFactory方法等
    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()) {
        //調(diào)用注冊(cè)到BeanFactory里的BeanPostProcessor的
        //postProcessBeforeInitialization
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    //如果Bean有初始化方法,則調(diào)用初始化方法
    //這里也有個(gè)重要的方法,如果Bean實(shí)現(xiàn)了InitializingBean接口
    //那么方法里會(huì)識(shí)別出來(lái)并調(diào)用afterPropertiesSet方法
    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()) {
         //調(diào)用注冊(cè)到BeanFactory里的BeanPostProcessor的
        //postProcessAfterInitialization
        //這里就是本文要介紹的AOP入口實(shí)現(xiàn)的地方
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
}

好了,通過(guò)上面源碼注釋可以發(fā)現(xiàn),Spring AOP是通過(guò)BeanPostProcessor.applyBeanPostProcessorsAfterInitialization在Bean實(shí)例化時(shí)進(jìn)行處理的,那么肯定會(huì)有一個(gè)負(fù)責(zé)實(shí)現(xiàn)動(dòng)態(tài)代理創(chuàng)建的BeanPostProcessor接口實(shí)現(xiàn)負(fù)責(zé)處理相關(guān)邏輯,其實(shí)這個(gè)接口實(shí)現(xiàn)類(lèi)就是AnnotationAwareAspectJAutoProxyCreator,AnnotationAwareAspectJAutoProxyCreator的相關(guān)方法會(huì)在需要的時(shí)候進(jìn)行代理類(lèi)的創(chuàng)建。

那么,AnnotationAwareAspectJAutoProxyCreator是在何時(shí)注冊(cè)到Spring BeanFactory中的呢?

2 Spring Boot自動(dòng)配置下AnnotationAwareAspectJAutoProxyCreator的注冊(cè)

Spring Boot通過(guò)注解EnableAutoConfiguration進(jìn)行自動(dòng)配置并引入相關(guān)組件,在spring.factoriesEnableAutoConfiguration就配置了AopAutoConfigurationAopAutoConfiguration就是AnnotationAwareAspectJAutoProxyCreator引入的地方。

//AopAutoConfiguration
@Configuration
@ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class, AnnotatedElement.class })
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {

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

    }

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

    }

}

可見(jiàn)AopAutoConfiguration的兩個(gè)內(nèi)部類(lèi)JdkDynamicAutoProxyConfigurationCglibAutoProxyConfiguration都被Configuration注解,且也都被EnableAspectJAutoProxy注解,EnableAspectJAutoProxy源碼如下:

//EnableAspectJAutoProxy
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {

    /**
     * Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
     * to standard Java interface-based proxies. The default is {@code false}.
     */
    boolean proxyTargetClass() default false;

    /**
     * Indicate that the proxy should be exposed by the AOP framework as a {@code ThreadLocal}
     * for retrieval via the {@link org.springframework.aop.framework.AopContext} class.
     * Off by default, i.e. no guarantees that {@code AopContext} access will work.
     * @since 4.3.1
     */
    boolean exposeProxy() default false;

}

EnableAspectJAutoProxy的注解@Import(AspectJAutoProxyRegistrar.class)向Spring BeanFactory中注冊(cè)了上文提到的AnnotationAwareAspectJAutoProxyCreator。

后續(xù)在創(chuàng)建Bean時(shí)會(huì)使用AnnotationAwareAspectJAutoProxyCreator進(jìn)行AOP代理的創(chuàng)建

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

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