"starter" 是一个用于简化 Maven 依赖管理的概念,它把所有依赖关系都打包在一起,可以帮助开发者快速集成和配置 Spring 项目中常用的库。
有点像我们去买一些必需品,然后有人打包成一个套餐售卖,我们就不需要一个一个再去找了,直接一次性打包拿走,节省了时间。
如何自定义实现一个 starter?
我举一个通用的示例。
首先创建一个 maven 项目,pom.xml 中添加 SpringBoot 和其他相关依赖。
<project ...>
<groupId>com.examplegroupId>
<artifactId>my-starterartifactId>
<version>1.0.0version>
<name>xxxname>
.....
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
dependencies>
project>
首先我们配置一个属性类,这样我们在配置文件中根据固定的前缀加属性就可以修改制定的配置:
@Configuration
@ConfigurationProperties(prefix = "spring.xxx")
@Data
public class XxxProperties {
private String host;
private Integer port;
}
然后创建一个自动配置类,需要使用 @Configuration 和 @ConditionalOnxxx() 注解来条件化的配置 Bean。
@Configuration
@EnableConfigurationProperties(XxxProperties.class)
public class MyAutoConfiguration {
@Autowired
priavte XxxProperties properties;
@Bean
@ConditionalOnMissingBean
public MyService myService() {
MyService service = new MyService();
service.setHost(properties.getHost());
service.setPort(properties.getPort());
return service;
}
}
像上面的代码就是当没有 MyService Bean 的时候,默认创建一个,并且属性来源于配置。
最后,在 src/main/resources/META-INF 目录下创建 spring.factories 文件,并在其中定义自动配置类。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.starter.MyAutoConfiguration
大功告成,就是这么简单,然后 maven 打包可以发布到中央仓库或者私有仓库即可。
最终其他项目引入这个 starter 就能直接使用:
<dependency>
<groupId>com.examplegroupId>
<artifactId>my-starterartifactId>
<version>1.0.0version>
dependency>
扩展可以参考企业级的 starter
例如 MyBatisPlus 的,我简单对照我们上面的步骤截几个图,大家可以简单感受下,有兴趣也自行去查看:
扩展 SpringBoot3.x spring.factories 问题
上面我们演示的是 SpringBoot2.x 版本。如果升级到 SpringBoot3.x 那么 spring.factories 就无法生效了,因为官方已经把它移除了。
可以看下官方文档:
spring.factories 功能在 Spring Boot 2.7已经废弃,并且会在 Spring Boot 3.0移除
这使得类似上述的 mybatis-plus 低版本都无法使用。
此时的方案就不能用 spring.factories ,需要在类路径下创建
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
文件。
然后文件的内容是:每个实现类的全类名单独一行。