• Spring的@Enable*注解的工作原理


    转自:https://blog.csdn.net/chengqiuming/article/details/81586948

    一 列举几个@Enable*注解的功能

    @EnableAspectJAutoProxy:开启对AspectJ自动代理的支持。
    @EnableAsync:开启异步方法支持。
    @EnableScheduling:开启计划任务
    @EnableWebMvc:开启Web Mvc配置功能
    二 点睛

    通过简单的@Enable*来开启一项功能的支持,从而避免自己配置大量的代码,大大降低了使用难度。

    通过观察这些@Enable*注解的源码,会发现所有的注解都有一个@Import注解,该注解是用来导入配置类的,这也意味着这些开启的实现是导入了一些自动配置的Bean。

    这些导入方式分三类,我们一探究竟。

    三 导入配置类方式

    1 直接导入配置类

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import(EurekaServerMarkerConfiguration.class)
    public @interface EnableEurekaServer {
    
    }


    直接导入配置类SchedulingConfiguration,SchedulingConfiguration注解了@Configuration,且注册了ScheduledAnnotationBeanPostProcessor的Bean,源码如下:

    @Configuration
    public class SchedulingConfiguration {
    
    @Bean(name = TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME)
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public ScheduledAnnotationBeanPostProcessor scheduledAnnotationProcessor() {
    return new ScheduledAnnotationBeanPostProcessor();
    }


    2 依据条件选配置类

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import(AsyncConfigurationSelector.class)
    public @interface EnableAsync {
    
    Class<? extends Annotation> annotation() default Annotation.class;
    boolean proxyTargetClass() default false;
    AdviceMode mode() default AdviceMode.PROXY; //默认值
    int order() default Ordered.LOWEST_PRECEDENCE;
    }


    AsyncConfigurationSelector通过条件来选择需要导入的配置类,AsyncConfigurationSelector的根接口是ImportSelector,这个接口需要实现selectImports方法,在该方法中进行了条件判断。如果adviceMode为PROXY,则返回ProxyAsyncConfiguration这个配置类;如果为ASPECTJ,则返回AspectJAsyncConfiguration配置类,源码如下:

    /**
         * Returns {@link ProxyAsyncConfiguration} or {@code AspectJAsyncConfiguration}
         * for {@code PROXY} and {@code ASPECTJ} values of {@link EnableAsync#mode()},
         * respectively.
         */
        @Override
        @Nullable
        public String[] selectImports(AdviceMode adviceMode) {
            switch (adviceMode) {
                case PROXY:
                    return new String[] {ProxyAsyncConfiguration.class.getName()};
                case ASPECTJ:
                    return new String[] {ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME};
                default:
                    return null;
            }
        }

    3 动态注册Bean

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import(AspectJAutoProxyRegistrar.class)
    public @interface EnableAspectJAutoProxy {
    boolean proxyTargetClass() default false;
    
    }

    AspectJAutoProxyRegistrar实现了ImportBeanDefinitionRegistrar接口,ImportBeanDefinitionRegistrar的作用是在运行时自动添加Bean到已有的配置类,通过重写下面方法:

    public void registerBeanDefinitions(
    AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry);
    其中importingClassMetadata参数用来获得当前配置类上的注解:BeanDefinitionRegistry参数用来注册Bean。源码如下:

    class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(
    AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    
    AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
    
    AnnotationAttributes enableAJAutoProxy =
    AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
    if (enableAJAutoProxy.getBoolean("proxyTargetClass")) {
    AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
    }
    }


    }
     
    ---------------------
    作者:chengqiuming
    来源:CSDN
    原文:https://blog.csdn.net/chengqiuming/article/details/81586948
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    如何让你的Sublime和Codeblocks支持C++11
    Python print不换行输出的替代方法
    阶梯博弈
    hdu4633_Polya定理
    Ural_1169_Pairs
    ACM竞赛中的魔方问题专题(不定时更新)
    LintCode 35. 翻转链表
    windows中mysql5.7中配置中文字符集和默认datadir
    CentOS7使用打开关闭防火墙与端口
    关于阿里巴巴开发手册"不得使用外键与级联,一切外键概念必须在应用层解决"的疑惑
  • 原文地址:https://www.cnblogs.com/drafire/p/10450855.html
Copyright © 2020-2023  润新知