Spring Boot 自定义 Starter 组件的技术指南
1、简述
Spring Boot 通过 Starter 机制,让开发者可以快速集成第三方组件。在企业级开发中,我们常常需要封装自己的 Starter 组件,以提高代码复用性,简化配置,并实现可插拔的模块化开发。
-
Spring Boot Starter 机制
-
如何创建一个自定义 Starter
-
如何实现 Starter 组件的热拔插
-
完整示例:自定义日志组件并支持热拔插
2、Spring Boot Starter 机制
Spring Boot Starter 是一组依赖和自动配置的集合,提供了一种约定优于配置的方式来集成第三方库。例如:
-
spring-boot-starter-web
(Web 开发) -
spring-boot-starter-data-jpa
(JPA 数据库访问) -
spring-boot-starter-actuator
(监控)
自定义 Starter 允许我们封装业务逻辑,使其像官方 Starter 一样易于使用。
3、创建自定义 Starter
我们以 日志记录组件 为例,开发一个 Starter,包含:
-
自动配置类
-
日志服务类
-
Spring Boot 配置绑定
-
SpringFactories 机制
实现自定义Starter要引用autoconfigure的Maven:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.1.8.RELEASE</version>
</dependency>
3.1 编写日志服务类
LogService
提供日志打印功能,支持自定义日志前缀。
package com.example.logstarter.service;
public class LogService {
private String logPrefix;
public LogService(String logPrefix) {
this.logPrefix = logPrefix;
}
public void log(String message) {
System.out.println(logPrefix + " " + message);
}
}
3.2 编写自动配置类
package com.example.logstarter.config;
import com.example.logstarter.service.LogService;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConditionalOnProperty(prefix = "custom.log", name = "enabled", havingValue = "true", matchIfMissing = true)
public class LogAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public LogService logService() {
return new LogService("[Default Log]");
}
}
-
@Configuration
:声明配置类。 -
@ConditionalOnProperty
:控制组件是否启用(默认启用)。 -
@ConditionalOnMissingBean
:防止已有LogService
时重复注册。
3.3 配置 spring.factories
在 resources/META-INF/spring.factories
中添加:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.logstarter.config.LogAutoConfiguration
Spring Boot 在启动时会自动加载 LogAutoConfiguration
。
3.4 在主应用引入 Starter
在 Spring Boot 主项目 的 pom.xml
添加:
<dependency>
<groupId>com.example</groupId>
<artifactId>log-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
然后在 application.yml
中启用:
custom:
log:
enabled: true
3.5 测试 Starter
在主应用中使用:
import com.example.logstarter.service.LogService;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
@Component
public class LogTestRunner implements CommandLineRunner {
private final LogService logService;
public LogTestRunner(LogService logService) {
this.logService = logService;
}
@Override
public void run(String... args) throws Exception {
logService.log("Spring Boot 自定义 Starter 成功!");
}
}
运行后输出:
[Default Log] Spring Boot 自定义 Starter 成功!
4、实现 Starter 的热拔插
在 Spring Boot 中,热拔插(Hot Plugging) 允许我们在不重启应用的情况下动态启用或禁用某些功能。
-
如何使用 @ConditionalOnClass 实现 Starter 组件的热拔插
-
与 @ConditionalOnProperty 的区别
完整示例:基于 @ConditionalOnClass 的日志组件
4.1 新增标记类
@ConditionalOnClass 用于检测某个类是否存在,如果存在,则加载相应的 Bean。例如:
@ConditionalOnClass(name = “com.example.ConfigMarker”)
只有 com.example.ConfigMarker 存在时,Spring Boot 才会加载该 Bean。
热拔插思路:
-
当 某个类 存在时,自动加载相关组件。
-
当 该类被删除 或 未引入依赖 时,不加载该组件,达到动态启用/禁用的目的。
通过自定义注解@EnableRegisterServer开关来控制热拔插技术:
import org.springframework.context.annotation.Import;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Import({ConfigMarker.class})
public @interface EnableRegisterServer {
}
4.2 启动注解
在启动类Application添加@EnableRegisterServer这样就可以启动LogService类实例:
@EnableRegisterServer
@SpringBootApplication
public class CsvApplication {
public static void main(String[] args) {
SpringApplication.run(CsvApplication.class, args);
}
}