zoukankan      html  css  js  c++  java
  • Spring Enable高级应用及原理

    Enable*

    之前的文章用到了一些Enable*开头的注解,比如EnableAsync、EnableScheduling、EnableAspectJAutoProxy、EnableCaching等,Enable表示开启/允许一项功能。

    Enable*工作原理

    我们只需要几个很简单的注解就能开启一个复杂的功能,这是多么简易的用法,这是怎么办到的?

    首先来看看计划任务@EnableScheduling的源代码

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

    主要核心的配置就是导入了一个配置文件,所以谜底也就接开了。

    @Import(SchedulingConfiguration.class)

    @Import用法

    来看看Import的源码

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Import {
    
        /**
         * {@link Configuration}, {@link ImportSelector}, {@link ImportBeanDefinitionRegistrar}
         * or regular component classes to import.
         */
        Class<?>[] value();
    
    }

    1、Configuration

    即上面的用法,直接导入Configuration配置类。

    2、ImportSelector

    根据条件选择导入不同的配置类,参考@EnableAsync

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import(AsyncConfigurationSelector.class)
    public @interface EnableAsync {
    public class AsyncConfigurationSelector extends AdviceModeImportSelector<EnableAsync> {
    
        private static final String ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME =
                "org.springframework.scheduling.aspectj.AspectJAsyncConfiguration";
    
        /**
         * {@inheritDoc}
         * @return {@link ProxyAsyncConfiguration} or {@code AspectJAsyncConfiguration} for
         * {@code PROXY} and {@code ASPECTJ} values of {@link EnableAsync#mode()}, respectively
         */
        @Override
        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、ImportBeanDefinitionRegistrar

    动态注册Bean,参考@EnableAspectJAutoProxy

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import(AspectJAutoProxyRegistrar.class)
    public @interface EnableAspectJAutoProxy {
    class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
    
        /**
         * Register, escalate, and configure the AspectJ auto proxy creator based on the value
         * of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
         * {@code @Configuration} class.
         */
        @Override
        public void registerBeanDefinitions(
                AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    
            AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
    
            AnnotationAttributes enableAspectJAutoProxy =
                    AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
            if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
                AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
            }
            if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
                AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
            }
        }
    
    }

    推荐阅读

    干货:免费领取2TB架构师四阶段视频教程

    面经:史上最全Java多线程面试题及答案

    工具:推荐一款在线创作流程图、思维导图软件

    分享Java干货,高并发编程,热门技术教程,微服务及分布式技术,架构设计,区块链技术,人工智能,大数据,Java面试题,以及前沿热门资讯等。

  • 相关阅读:
    BADI 笔记
    ALV 常用功能 转载
    F4字段搜索帮助
    全省各地均可拨打劳动违法投诉电话:12333
    小结SQL Server连接失败错误及解决
    sql server日志已满处理方法
    VC6.0快捷键大全
    Eclipse下UML插件及安装
    Delphi错误:"External exception C0000235"
    delphi中临界操作方法
  • 原文地址:https://www.cnblogs.com/java-stack/p/11952600.html
Copyright © 2011-2022 走看看