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