转载

Springboot源码分析之EnableAspectJAutoProxy

摘要:

Spring Framwork 的两大核心技术就是 IOCAOPAOPSpring 的产品线中有着大量的应用。如果说反射是你通向高级的基础,那么代理就是你站稳高级的底气。 AOP 的本质也就是大家所熟悉的 CGLIB 动态代理技术,在日常工作中想必或多或少都用过但是它背后的秘密值得我们去深思。本文主要从 Spring AOP 运行过程上,结合一定的源码整体上介绍 Spring AOP 的一个运行过程。知其然,知其所以然,才能更好的驾驭这门核心技术。

@Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import({AspectJAutoProxyRegistrar.class})
    public @interface EnableAspectJAutoProxy {
        //表明该类采用CGLIB代理还是使用JDK的动态代理
        boolean proxyTargetClass() default false;
         /**
         * @since 4.3.1 代理的暴露方式:解决内部调用不能使用代理的场景  默认为false表示不处理
         * true:这个代理就可以通过AopContext.currentProxy()获得这个代理对象的一个副本(ThreadLocal里面),从而我们可以很方便得在Spring框架上下文中拿到当前代理对象(处理事务时很方便)
         * 必须为true才能调用AopContext得方法,否则报错:Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available.
         */
        boolean exposeProxy() default false;
    }

所有的 EnableXXX 驱动技术都得看他的 @Import ,所以上面最重要的是这一句 @Import(AspectJAutoProxyRegistrar.class) ,下面看看它

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
        AspectJAutoProxyRegistrar() {
        }
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
            //注册了一个基于注解的自动代理创建器   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 是一个项容器注册自动代理创建器

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

说明: spring 容器的注解代理创建器就是 AnnotationAwareAspectJAutoProxyCreator

@Nullable
        private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
            Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
          //这里如果我们自己定义了这样一个自动代理创建器就是用我们自定义的
            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());
                  /** 
                   *用户注册的创建器,必须是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);
          //此处注意,增加了一个属性:最高优先级执行,后面会和@Async注解一起使用的时候起关键作用
            beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
            beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
            registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
            return beanDefinition;
        }

我们就成功的注入了一个 BeanAnnotationAwareAspectJAutoProxyCreator 基于注解的自动代理创建器

Spring中自动创建代理器

Springboot源码分析之EnableAspectJAutoProxy

由此可见, Spring 使用 BeanPostProcessor 让自动生成代理。基于 BeanPostProcessor 的自动代理创建器的实现类,将根据一些规则在容器实例化 Bean 时为匹配的 Bean 生成代理实例。

AbstractAutoProxyCreator 是对自动代理创建器的一个抽象实现。最重要的是,它实现了 SmartInstantiationAwareBeanPostProcessor 接口,因此会介入到 Spring IoC 容器 Bean 实例化的过程。

SmartInstantiationAwareBeanPostProcessor 继承 InstantiationAwareBeanPostProcessor 所以它最主要的 职责是在 bean 的初始化前,先会执行所有的 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation ,谁第一个返回了不为 nullBean ,后面就都不会执行了 。然后会再执行 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 的三级缓存中的其中一环,当你调用 Object earlySingletonReference = getSingleton(beanName, false); 时候就会触发,其实还有一个地方 exposedObject = initializeBean(beanName, exposedObject, mbd); 也会触发导致返回一个代理对象。

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;
        }

强调: 这2个地方虽然都有后置增强的作用,但是 @Async 所使用的 AsyncAnnotationBeanPostProcessor 不是 SmartInstantiationAwareBeanPostProcessor 的实现类,所以此处会导致 @Transactional@Async 处理循环依赖时候的不一致性。对于循环依赖后续会有单独章节进行分享。

AbstractAdvisorAutoProxyCreator

如何创建代理对象后续文章在进行分析。

原文  http://www.cnblogs.com/qinzj/p/11397253.html
正文到此结束
Loading...