leo-space

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

你好,我是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将在此系列文章的第三篇中介绍。

posted on 2023-08-13 22:01  leo_space  阅读(46)  评论(0编辑  收藏  举报