• Spring Enable*高级应用及原理


    Enable*

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

    Enable*工作原理

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

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

    1. @Target(ElementType.TYPE)

    2. @Retention(RetentionPolicy.RUNTIME)

    3. @Import(SchedulingConfiguration.class)

    4. @Documented

    5. public @interface EnableScheduling {

    6. }

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

    @Import(SchedulingConfiguration.class)

    @Import用法

    来看看Import的源码

    1. @Target(ElementType.TYPE)

    2. @Retention(RetentionPolicy.RUNTIME)

    3. @Documented

    4. public @interface Import {

    5.    /**

    6.     * {@link Configuration}, {@link ImportSelector}, {@link ImportBeanDefinitionRegistrar}

    7.     * or regular component classes to import.

    8.     */

    9.    Class<?>[] value();

    10. }

    1、Configuration

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

    2、ImportSelector

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

    1. @Target(ElementType.TYPE)

    2. @Retention(RetentionPolicy.RUNTIME)

    3. @Documented

    4. @Import(AsyncConfigurationSelector.class)

    5. public @interface EnableAsync {

    1. public class AsyncConfigurationSelector extends AdviceModeImportSelector<EnableAsync> {

    2.    private static final String ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME =

    3.            "org.springframework.scheduling.aspectj.AspectJAsyncConfiguration";

    4.    /**

    5.     * {@inheritDoc}

    6.     * @return {@link ProxyAsyncConfiguration} or {@code AspectJAsyncConfiguration} for

    7.     * {@code PROXY} and {@code ASPECTJ} values of {@link EnableAsync#mode()}, respectively

    8.     */

    9.    @Override

    10.    public String[] selectImports(AdviceMode adviceMode) {

    11.        switch (adviceMode) {

    12.            case PROXY:

    13.                return new String[] { ProxyAsyncConfiguration.class.getName() };

    14.            case ASPECTJ:

    15.                return new String[] { ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME };

    16.            default:

    17.                return null;

    18.        }

    19.    }

    20. }

    3、ImportBeanDefinitionRegistrar

    动态注册Bean,参考@EnableAspectJAutoProxy

    1. @Target(ElementType.TYPE)

    2. @Retention(RetentionPolicy.RUNTIME)

    3. @Documented

    4. @Import(AspectJAutoProxyRegistrar.class)

    5. public @interface EnableAspectJAutoProxy {

    1. class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

    2.    /**

    3.     * Register, escalate, and configure the AspectJ auto proxy creator based on the value

    4.     * of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing

    5.     * {@code @Configuration} class.

    6.     */

    7.    @Override

    8.    public void registerBeanDefinitions(

    9.            AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

    10.        AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

    11.        AnnotationAttributes enableAspectJAutoProxy =

    12.                AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);

    13.        if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {

    14.            AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);

    15.        }

    16.        if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {

    17.            AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);

    18.        }

    19.    }

    20. }

  • 相关阅读:
    SpringMVC:JSON讲解
    SpringMVC:文件上传和下载
    字符串的使用
    python中的作用域与名称空间
    深、浅copy
    代码块与小数据池之间的关系
    关于敏感字符的筛选替换
    列表的增、删、改、查
    最简三级菜单
    python2.x与python3.x的区别
  • 原文地址:https://www.cnblogs.com/zhangyu1024/p/9139829.html
Copyright © 2020-2023  润新知