美文网首页
SpringBoot:如何书写一个自定义的Enable*注解

SpringBoot:如何书写一个自定义的Enable*注解

作者: 花花大脸猫 | 来源:发表于2021-08-29 12:05 被阅读0次

Spring提供了一系列Enable*的自定义注解,这些注解本质上只是用于启用spring boot管理的一些功能特性,比如 [EnableWebMvc] 注解会激活提供基于springmvc的web功能支持, [EnableAsync]注解会激活异步的功能支持。
我比较好奇这些自定义注解是如何工作的,进而促使我写出这篇文章记录我的理解,这些自定义注解的支持,可以理解为SPI的一部分,如果后续的内部实现有变化,对应的支持可能会中断。

1.新建自定义的注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface EnableCustomFeature {}

2.应用此注解到配置类

@Configuration
@EnableCustomFeature 
public class CustomFeatureConfig {}

3.这时候需要在EnableCustomFeature 类中通过@Import的方式引入一系列需要前置处理的Bean类

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import(SomeBeanConfiguration.class)
@interface EnableCustomFeature {}

上述通过@Import方式做的原因,主要是将@Import标记的配置类中的bean作为ApplicationContext处理

@Configuration
class SomeBeanConfiguration {
 
    @Bean
    public String aBean1() {
        return "aBean1";
    }
 
    @Bean
    public String aBean2() {
        return "aBean2";
    }
}

使用Selector选择器启用Enable自定义注解

自定义Enable*注解也可以实现复杂的功能,可以通过的上下文启用不同的bean实现功能。在Springboot中@EnableCaching就是这样的例子,可以通过不同的缓存实现来激活对应的bean配置。

示例如下:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import(SomeBeanConfigurationSelector.class)
public @interface EnableCustomFeatureSelector {
    String criteria() default "default";
}

上述示例中,自定义的注解中有一个criteria自定义注解属性字段,默认值为default,后面我们需要做的就是根据criteria的值激活两种不同的bean功能集合:

import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
 
public class SomeBeanConfigurationSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        AnnotationAttributes attributes =
                AnnotationAttributes.fromMap(
                        importingClassMetadata.getAnnotationAttributes(EnableSomeBeansSelector.class.getName(), false));
        String criteria = attributes.getString("criteria");
        if (criteria.equals("default")) {
            return new String[]{"enableannot.selector.SomeBeanConfigurationDefault"};
        }else {
            return new String[]{"enableannot.selector.SomeBeanConfigurationType1"};
        }
    }
}
 
@Configuration
class SomeBeanConfigurationType1 {
 
    @Bean
    public String aBean() {
        return "Type1";
    }
 
}
 
@Configuration
class SomeBeanConfigurationDefault {
 
    @Bean
    public String aBean() {
        return "Default";
    }
 

所以如果criteria字段值为 "default",就会加载SomeBeanConfigurationDefault, 否则就是加载SomeBeanConfigurationType1。

参考链接:http://www.java-allandsundry.com/2015/04/spring-enable-annotation-writing-custom.html

相关文章

网友评论

      本文标题:SpringBoot:如何书写一个自定义的Enable*注解

      本文链接:https://www.haomeiwen.com/subject/gwbmiltx.html