查看原文
其他

Spring Enable*高级应用及原理

2017-09-20 javastack Java技术栈


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


看完有没有收获?

分享到朋友圈给更多的人吧。




您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存