Spring Enable*高级应用及原理

mac2022-06-30  19

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

       }

   }

 

}

转载于:https://www.cnblogs.com/zhangyu1024/p/9139829.html

最新回复(0)