Spring Boot源码-Spring AOP创建代理的入口


1 概述
2 Spring Boot自动配置下AnnotationAwareAspectJAutoProxyCreator的注册

1 概述

了解过Spring源码的都知道Spring是通过动态代理实现AOP的,Spring中实现动态代理有两种方式,分别为JDK原生动态代理和CGLIB,这里不对动态代理的具体实现进行介绍,主要介绍Spring实现动态代理的相关入口。

在进行接下来的介绍之前,我们要先看下Spring在创建一个Bean的实例之后时如何对Bean进行初始化的,AbstractAutowireCapableBeanFactory在实例化一个Bean之后,会分别调用populateBeaninitializeBean进行Bean的依赖注入和初始化,这里我们仅仅看initializeBean的实现:

//AbstractAutowireCapableBeanFactory
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
    //如何Bean实现了一些Aware接口,则调用相应的方法,比如
    //BeanFactoryAware的setBeanFactory方法等
    if (System.getSecurityManager() != null) {
        AccessController.doPrivileged((PrivilegedAction) () -> {
            invokeAwareMethods(beanName, bean);
            return null;
        }, getAccessControlContext());
    }
    else {
        invokeAwareMethods(beanName, bean);
    }

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        //调用注册到BeanFactory里的BeanPostProcessor的
        //postProcessBeforeInitialization
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    //如果Bean有初始化方法,则调用初始化方法
    //这里也有个重要的方法,如果Bean实现了InitializingBean接口
    //那么方法里会识别出来并调用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()) {
         //调用注册到BeanFactory里的BeanPostProcessor的
        //postProcessAfterInitialization
        //这里就是本文要介绍的AOP入口实现的地方
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
}

好了,通过上面源码注释可以发现,Spring AOP是通过BeanPostProcessor.applyBeanPostProcessorsAfterInitialization在Bean实例化时进行处理的,那么肯定会有一个负责实现动态代理创建的BeanPostProcessor接口实现负责处理相关逻辑,其实这个接口实现类就是AnnotationAwareAspectJAutoProxyCreatorAnnotationAwareAspectJAutoProxyCreator的相关方法会在需要的时候进行代理类的创建。

那么,AnnotationAwareAspectJAutoProxyCreator是在何时注册到Spring BeanFactory中的呢?

2 Spring Boot自动配置下AnnotationAwareAspectJAutoProxyCreator的注册

Spring Boot通过注解EnableAutoConfiguration进行自动配置并引入相关组件,在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 {

    }

}

可见AopAutoConfiguration的两个内部类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中注册了上文提到的AnnotationAwareAspectJAutoProxyCreator

后续在创建Bean时会使用AnnotationAwareAspectJAutoProxyCreator进行AOP代理的创建

你可能感兴趣的:(Spring Boot源码-Spring AOP创建代理的入口)