Spring Enable*高级应用及原理

来源:互联网 发布:如何卖数据 编辑:程序博客网 时间:2024/06/09 20:57

Enable*

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

Enable*工作原理

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

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

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

@Import(SchedulingConfiguration.class)

@Documented

public@interfaceEnableScheduling{

}

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

@Import(SchedulingConfiguration.class)

@Import用法

来看看Import的源码

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

@Documented

public@interfaceImport{

/**

* {@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@interfaceEnableAsync{

publicclassAsyncConfigurationSelectorextendsAdviceModeImportSelector{

privatestaticfinalStringASYNC_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

publicString[]selectImports(AdviceModeadviceMode){

switch(adviceMode){

casePROXY:

returnnewString[]{ProxyAsyncConfiguration.class.getName()};

caseASPECTJ:

returnnewString[]{ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME};

default:

returnnull;

}

}

}

3、ImportBeanDefinitionRegistrar

动态注册Bean,参考@EnableAspectJAutoProxy

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Import(AspectJAutoProxyRegistrar.class)

public@interfaceEnableAspectJAutoProxy{

classAspectJAutoProxyRegistrarimplementsImportBeanDefinitionRegistrar{

/**

* 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

publicvoidregisterBeanDefinitions(

AnnotationMetadataimportingClassMetadata,BeanDefinitionRegistryregistry){

AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

AnnotationAttributesenableAspectJAutoProxy=

AnnotationConfigUtils.attributesFor(importingClassMetadata,EnableAspectJAutoProxy.class);

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

AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);

}

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

AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);

}

}

}


原创粉丝点击