3.6 Spring高级话题: @Enable*注解的工作原理
3.6 @Enable*注解的原理
- @Enable*注解枚举
1.1 @EnableScheduling //开启计划任务支持
1.2 @EnableAsync //开启同步支持
1.3 @EnableAspectJAutoProxy//开启对AspectJ的自动代理支持
1.4 @EnableWebMvc//开启WebMvc支持
1.5 @EnableConfigurationProperties//开启对 @EnableConfigurationProperties的支持
1.6 @EnableCaching//开启缓存支持
1.7 @EnableTransactionManagement//开启事务支持
- @Enable*的注解都有@Import注解 -> @Enable是导入一些自动配置的类
导入的方式主要有3种
2.1 直接导入配置 -> EnableScheduling导入的SchedulingConfiguration
2.2 依据条件选择配置类 ->
需要实现ImportSelector接口,根据情况来配置不同的类
2.3 动态注册Bean -> EnableAspectJAutoProxy 导入的 AspectJAutoProxyRegistrar
继承了ImportBeanDefinitionRegistrar接口,(运行时动态的添加Bean到已有的配置)
实现registerBeanDefinitions
1.@EnableScheduling的注解示例
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(SchedulingConfiguration.class)
@Documented
public @interface EnableScheduling {
}
2.直接导入配置样例
@Configuration
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class SchedulingConfiguration {
@Bean(name = TaskManagementConfigUtils.SCHEDULED_ANNOTATION_PROCESSOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public ScheduledAnnotationBeanPostProcessor scheduledAnnotationProcessor() {
return new ScheduledAnnotationBeanPostProcessor();
}
}
3.依据条件选择配置
class EnableConfigurationPropertiesImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata metadata) {
MultiValueMap<String, Object> attributes = metadata.getAllAnnotationAttributes(
EnableConfigurationProperties.class.getName(), false);
Object[] type = attributes == null ? null
: (Object[]) attributes.getFirst("value");
if (type == null || type.length == 0) {
return new String[] {
ConfigurationPropertiesBindingPostProcessorRegistrar.class
.getName() };
}
return new String[] { ConfigurationPropertiesBeanRegistrar.class.getName(),
ConfigurationPropertiesBindingPostProcessorRegistrar.class.getName() };
}
4.动态注册Bean
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);
}
}
}