实现一个spring boot starter(二)——手写一个简易的starter
你好,我是leo,在上一篇文章中,介绍了java SPI机制的原理,它是理解spring boot starter的基础。那么spring boot starter是怎么使用SPI的,又是如何实现的呢?
一:SPI机制
二:手写一个简易的starter
三:自动装配功能扩展
还是先来看看最常用的spring-boot-starter是如何运作的
初始化的spring boot项目,默认会添加spring-boot-starter的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>3.1.2</version>
</dependency>
starter的pom文件中,dependencies节点引入了最常用的几个依赖
点击查看代码
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>3.1.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>3.1.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
<version>3.1.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>2.1.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>6.0.11</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.33</version>
<scope>compile</scope>
</dependency>
</dependencies>
这就是starter的第一个功能了:预定义一组依赖项,让使用starter的人不必手动管理复杂的的依赖关系,从而减少了配置和版本冲突的风险。
starter的第二个功能,就是引入spring-boot-autoconfigure,实现自动装配的基础功能。
假设我们要写一个公共框架给业务团队的伙伴使用,那么自定义一个starter的具体步骤如下:
首先定义一个接口,这个接口是我们自己的公共框架所提供的某个功能。
public interface HelloService {
String getInfo();
}
然后是公共框架中该接口的实现类:
public class HelloServiceImpl implements HelloService {
@Override
public String getInfo() {
return "ok";
}
}
注意此处的实现类并没有@Component注解,也就是说,如果在公共框架中不做自动装配,那么在引用公共框架的项目中,是无法获取到HelloService的Bean。
接下来定义自动装配的过程
@Configuration
public class HelloServiceAutoconfiguration
{
@Bean
@ConditionalOnMissingBean(HelloService.class)
public HelloService helloService(){
HelloService helloService = new HelloServiceImpl();
return helloService;
}
}
本质上是一个配置类,实例化了HelloServiceImpl。
接下来在文件公共框架的/resource/META-INF/spring.factories文件中加入配置
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.common.service.HelloServiceAutoconfiguration
以上就是AutoConfiguration模块的内容了,最后,再新增一个starter模块,引入HelloServiceAutoconfiguration模块,如果还有其他的Autoconfiguration,也可以一起引入,这样就可以把starter打包部署到maven了。
业务团队的伙伴怎么使用这个公共框架呢?很简单,pom文件中引入starter,就能开箱即用了。
来实验下:
引入公共框架的依赖
<dependency>
<groupId>com.example</groupId>
<artifactId>common-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
@SpringBootApplication
public class NewProApplication {
public static void main(String[] args) {
ApplicationContext context= SpringApplication.run(NewProApplication.class, args);
HelloService helloService= context.getBean(HelloService.class);
helloService.getInfo();
}
}
注意此处的helloService是可以从spring容器中拿到Bean对象的,这就证明HelloService接口已经自动装配好了。当然,在业务团队的项目中,用@Autowired注解注入HelloService的Bean也是没有问题的。
以上就是一个最简单的starter,总结一下starter的功能,无非两个:一是管理一组依赖,二是提供自动装配功能。实际应用中,自动装配还有很多需要考虑的点,leo将在此系列文章的第三篇中介绍。