天天看點

Spring Enable*進階應用及原理

Enable*

之前的文章用到了一些Enable*開頭的注解,比如EnableAsync、EnableScheduling、EnableAspectJAutoProxy、EnableCaching等,Enable表示開啟/允許一項功能。

Enable*工作原理

我們隻需要幾個很簡單的注解就能開啟一個複雜的功能,這是多麼簡易的用法,這是怎麼辦到的?

首先來看看計劃任務@EnableScheduling的源代碼

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

@Import(SchedulingConfiguration.class)

@Documented

public@interfaceEnableScheduling{

}

主要核心的配置就是導入了一個配置檔案,是以謎底也就接開了。

@Import用法

來看看Import的源碼

public@interfaceImport{

/**

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

* or regular component classes to import.

*/

Class[]value();

1、Configuration

即上面的用法,直接導入Configuration配置類。

2、ImportSelector

根據條件選擇導入不同的配置類,參考@EnableAsync

@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

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

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