Spring Boot EnableXxx

2023-03-27 13:56:30

前言

Spring boot 自带了很多@EnableXxx这样的注解,通过这些注解我们可以很方便地启用某些功能,比如@EnableAutoConfiguration用来开启自动装配的功能。内部实现主要是通过@Import注解将指定的类实例注入之Spring IOC Container中,从下面代码可以看到@EnableAutoConfiguration的@Import

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
…………
}

@Import注解

spring boot 的@Import注解可以配置三种不同的class,根据不同的场景来选择不同的注入方式

  • 普通的bean或者带有@Configuration的bean 直接注入
  • 实现ImportSelector接口注入
  • 实现ImportBeanDefinitionRegistrar接口注入
    下面使用这三种不同方式的实例来演示一下
  1. 先创建三个需要被注入的类
public class LoggerService {
    public void saveLog(String log){
        System.out.println("log is saved");
    }
}
public class MonitorService {
    public  void saveMonitor(){
        System.out.println("cpu、memory is saved");
    }
}
public class CounterService {
    public void add(int count ){
        System.out.println("count is added");
    }
}
  1. 针对MonitorServic我们使用ImportSelector的方式来注入,这里需要创建ImportSelector的实现类
public class MonitorImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        AnnotationAttributes annotationAttributes = AnnotationAttributes.fromMap(
                importingClassMetadata.getAnnotationAttributes(
                        EnableCustService.class.getName()));
        //在这里可以拿到所有注解的信息,可以根据不同注解的和注解的属性来返回不同的class,
        // 从而达到开启不同功能的目的
        return new String[]{MonitorService.class.getName()};
    }
}
  1. 针对CounterService我们使用ImportBeanDefinitionRegistrar的方式来注入,这里需要创建ImportSelector的实现类
public class CounterDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
   @Override
   public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
       Class beanClass = CounterService.class;
       RootBeanDefinition beanDefinition = new RootBeanDefinition(beanClass);
       String beanName = StringUtils.uncapitalize(beanClass.getSimpleName());
       //在这里可以拿到所有注解的信息,可以根据不同注解来返回不同的class,从而达到开启不同功能的目的
       //通过这种方式可以自定义beanName
       registry.registerBeanDefinition(beanName, beanDefinition);
   }
}
  1. 自定@EnableXXX注解
    准备工作做好后,我们开始创建自定义@EnableCustService
@Import({LoggerService.class,MonitorImportSelector.class,
         CounterDefinitionRegistrar.class})
public @interface EnableCustService {

}
  1. 模拟使用@EnableCustService
@EnableCustService
@SpringBootApplication
public class SpringbootCodeMain {
    public static void main(String[] args) {
        ConfigurableApplicationContext applicationContext  = SpringApplication.run(SpringbootCodeMain.class, args);
        System.err.println("-->"+applicationContext.getBean(LoggerService.class));
        System.err.println("-->"+applicationContext.getBean(MonitorService.class));
        System.err.println("-->"+applicationContext.getBean(CounterService.class));
    }
}
  • 作者:Glory丶笨小孩
  • 原文链接:https://blog.csdn.net/lht931942788/article/details/123510884
    更新时间:2023-03-27 13:56:30