猿创征文|Spring Boot 中 starter的原理

这是很久之前定下的一个系列,这个事情因为被一些其他事情耽搁,一直没有整理,罪过

springboot的starter 是整个springboot 的核心,官方的,开源的插件非常多。

Spring Boot学习大纲,可以留言自己想了解的技术点_香菜聊游戏的博客-CSDN博客

1、starter的使用

本来不想写这个部分,因为只要是java的程序基本上都知道咋回事,为了文章的上下文叙述方便,简单的说一下

简单说下Springboot项目增加监控的情况,在pom中增加下面的配置就会启动监控插件了。是不是很简单

<dependency> 
  <groupId>org.springframework.boot</groupId>  
  <artifactId>spring-boot-starter-actuator</artifactId> 
</dependency>

默认情况下,通过web端只可访问http://localhost:8080/actuator/health

当然也有一些配置可以自己配置在properties或者yaml中

# 访问端口
management.server.port=8081
# 根路径
management.endpoints.web.base-path=/actuator/z
# web端允许的路径
management.endpoints.web.exposure.include=*

看起来有点简单啊,只要这么几行代码就给应用增加了监控功能,是真的方便,即插即用

2、starter的原理

作为一个使用者,肯定想知道到底怎么运行的,为什么就这么简单就启动了。带着问题学习

  • 程序的入口在哪里
  • 怎么将bean 放置到 bean容器中
  • 各个插件之间的依赖是怎么判断的
  • 自动配置是咋回事

2.1 程序的入口在哪里

在 resource/META-INF 目录下名称为 spring.factories 的文件有启动的入口

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\

这句话就是启动一个配置类,也是入口

2.2 怎么将bean 放置到 bean容器中

通过EnableAutoConfiguration 会启动配置类,在配置类中通过@Bean 注解,返回一个bean就可以将bean

加入到bean容器中

2.3 各个插件之间的依赖是怎么判断的

这里主要是condition注解的使用,常用的condition主要有下面这些

@ConditionalOnBean:当容器里有指定Bean的条件下

@ConditionalOnClass:当类路径下有指定类的条件下

@ConditionalOnJava:基于JVM版本作为判断条件

@ConditionalOnMissingBean:当容器里没有指定Bean的情况下

@ConditionalOnMissingClass:当类路径下没有指定类的条件下

@ConditionalOnNotWebApplication:当前项目不是Web项目的条件下

@ConditionalOnProperty:指定的属性是否有指定的值

@ConditionalOnResource:类路径是否有指定的值

@ConditionalOnSingleCandidate:当指定Bean在容器中只有一个,或者虽然有多个但是指定首选Bean

@ConditionalOnWebApplication:当前项目是Web项目的条件下。

上面@ConditionalOnXXX都是组合@Conditional元注解,使用了不同的条件Condition

3、自定义starter

3.1 starter的命名规范

spring 官方建议的规则如下:

  • 官方:spring-boot-starter-{moduleName}
  • 非官方:{moduleName}-spring-boot-starter

3.2 自定义步骤

  1. 新建Maven项目,在项目的POM文件中定义使用的依赖;
  2. 新建配置类,写好配置项和默认的配置值,指明配置项前缀;
  3. 新建自动装配类,使用@Configuration和@Bean来进行自动装配;
  4. 新建spring.factories文件,指定Starter的自动装配类;

3.3 show me code

创建springboot项目,pom 如下,我删除了一些无用的配置。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.3</version>
    <relativePath/> 
  </parent>
  <groupId>org.example</groupId>
  <artifactId>xiangcai-sprint-boot-starter</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>
  <name>xiangcai-sprint-boot-starter</name>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
    </dependency>
  </dependencies>
</project>

spring.factories

org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.example.config.BootConfig

CarawayService.java ,随便创建了一个类

public class CarawayService {

    public void sayHello() {
        System.out.println("Hello  world");
    }
}

BootConfig.java 配置类,可以读取配置到变量,也可以创建bean到容器

@Configuration
public class BootConfig {

    @Bean
    public CarawayService carawayService(){
        System.out.println("xxxxxxxxx");
        return new CarawayService();
    }
}

完整的项目结构如下

下面开始打包,并且放到本地仓库,如果有需要可以推送到远程仓库

下面找个项目,在新项目中引入插件,在pom.xml中增加配置

<dependency>
   <groupId>org.example</groupId>
   <artifactId>xiangcai-sprint-boot-starter</artifactId>
   <version>1.0-SNAPSHOT</version>
</dependency>

验证下服务是否加载到bean容器中

ConfigurableApplicationContext run = SpringApplication.run(TransferAppApplication.class, args);
CarawayService carawayService = (CarawayService) run.getBean("carawayService");
carawayService.sayHello();

可以看到输出的两行

总结

starter的入口是spring.factories ,这是服务的入口,注意存放的路径,注意格式

配置的导入和常规的config配置一样

starter的入口是spring.factories ,这是服务的入口,注意存放的路径,注意格式

配置的导入和常规的config配置一样

猜你喜欢

转载自blog.csdn.net/perfect2011/article/details/126606486