spring boot 自定义@EnableXXX注解

本文介绍如何在Spring Boot中自定义@EnableXXX注解来启用特定功能,包括使用@Import注解的不同方式注入Bean,如普通Bean、实现ImportSelector和ImportBeanDefinitionRegistrar接口的类。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

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

自定@EnableXXX注解

准备工作做好后,我们开始创建自定义@EnableCustService

@Import({LoggerService.class,MonitorImportSelector.class,
         CounterDefinitionRegistrar.class})
public @interface EnableCustService {

}

模拟使用@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));
    }
}

启动程序输出:
–>com.maple.learn.enable.LoggerService@4943defe
–>com.maple.learn.enable.MonitorService@5eefa415
–>com.maple.learn.enable.CounterService@181d7f28

本文的项目代码git地址:https://github.com/amapleleaf/springboot-code.git ,本文只是讲了如何使用@EnableXXX,如果想了解其原理可以参考本人的另一篇文章<<spring boot自动装配之@EnableAutoConfiguration详解>>

### Spring Boot 中 `@Enable` 类型注解的功能与使用 #### 启用特定功能的机制 在 Spring Boot 应用程序中,`@Enable*` 注解用于开启框架中的某些特性或模块。这类注解通常通过集成 `ImportSelector` 或者 `ImportBeanDefinitionRegistrar` 接口来注册额外的 Bean 定义或者配置类到应用程序上下文中[^3]。 #### 实现方式 具体来说,当开发者创建了一个带有 `@Enable*` 的自定义注解并将其应用到某个配置类上时,Spring 将会在解析该注解的过程中调用相应的逻辑以完成指定行为。例如,在 `@EnableAsync` 这样的标准注解里,它实现了异步方法的支持;而如果要构建自己的 `@EnableXXX` 注解,则可以通过继承上述提到的一个或两个接口来自定义加载过程[^4]。 #### 示例代码展示如何创建和运用自定义 `@Enable` 注解 下面是一个简单的例子展示了怎样利用 `@EnableTestService` 来注入服务对象: ```java // 自定义 Enable 注解 public @interface EnableTestService { String value() default ""; } @Configuration @EnableTestService("hello") @SpringBootApplication public class TestApplication{ public static void main(String[] args) { ApplicationContext applicationContext = SpringApplication.run(TestApplication.class, args); // 获取由自定义 Enable 注解管理的服务实例 TestService testService = applicationContext.getBean(TestService.class); System.out.println("编码后的 appName:" + testService.getEncodedAppName()); } } ``` 这段代码说明了如何在一个 Spring Boot 主应用程序类中标记一个自定义的 `@EnableTestService` 注解,并且演示了之后可以从容器获取相应类型的 bean 并对其进行操作的过程。 #### 关键点分析 对于像 `@EnableApiClients` 这样更复杂的场景,其核心在于关联至 `@Import` 注解下的目标处理器类。这意味着每当此启用了 API 客户端支持的注解放置在启动类之上时,就会触发导入特定组件的动作,从而允许进一步处理标记有 `@ApiClient` 的客户端实现类[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值