首页 > 其他分享 >如何编写一个 SpringBoot 的 Starter

如何编写一个 SpringBoot 的 Starter

时间:2022-11-25 21:26:44浏览次数:72  
标签:cn spring sp boot 编写 config public Starter SpringBoot

一、什么是 Starter?

在开发过程中我们就经常使用到各种 starter,比如mybatis-spring-boot-starter,只需要进行简单的配置即可使用,就像一个插件非常方便。这也是 SpringBoot 非常重要的一个特性——自动化配置。

二、实现

2.1 创建一个 Maven 项目并配置 pom.xml

命名规范: Spring 官方的Starter命名格式一般是spring-boot-starter-{name},比如spring-boot-starter-web 。而非官方的,官方建议artifactId命名应该遵循 {name}-spring-boot-starter的格式,如example-spring-boot-starter

pom文件

<?xml version="1.0" encoding="UTF-8"?>
<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>

    <groupId>cn.sp</groupId>
    <artifactId>example-spring-boot-starter</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <spring-boot.version>2.1.5.RELEASE</spring-boot.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
    </dependencies>


    <dependencyManagement>
        <dependencies>
            <dependency>
                <!-- Import dependency management from Spring Boot -->
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

</project> 

spring-boot-configuration-processor 的作用是编译时生成 spring-configuration-metadata.json ,此文件主要给IDE使用,ctlr+鼠标左键点击配置文件(如application.properties)上相关配置属性,即可跳转到配置此属性的类中。

我们要实现的一个小功能是读取配置文件上cn.sp.config的字符串,然后按照给定的分隔符进行分割。

2.2 编写配置文件读取类

@ConfigurationProperties(prefix = "cn.sp")
public class StarterServiceProperties {

    private String config;

    public String getConfig() {
        return config;
    }

    public void setConfig(String config) {
        this.config = config;
    }
}

2.3 编写 Service

public class StarterService {

    private String config;

    public StarterService(String config){
        this.config = config;
    }

    public String[] split(String separatorChar){
        
        return this.config.split(separatorChar);
    }
}

2.4 编写自动配置类(重点)

package cn.sp.autoconfigure; 
 
@Configuration 
@ConditionalOnClass(StarterService.class) 
//@ConditionalOnProperty(prefix = "cn.sp",value = "enable",matchIfMissing = true) 
@EnableConfigurationProperties(StarterServiceProperties.class) 
public class StarterAutoConfigure { 
 
	@Autowired 
	private StarterServiceProperties properties; 
 
    @Bean 
    @ConditionalOnMissingBean 
    @ConditionalOnProperty(prefix = "cn.sp",value = "enabled",havingValue = "true") 
    StarterService starterService(){ 
    	return new StarterService(properties.getConfig()); 
	} 
} 

说下这几个注解的作用:

  • @ConditionalOnClass:当classpath下发现该类的情况下进行自动配置。
  • @EnableConfigurationProperties:使使用 @ConfigurationProperties 注解的类生效。
  • @ConditionalOnMissingBean:当 Spring 上下文中不存在该 Bean 时生效。
  • @ConditionalOnProperty(prefix = "cn.sp",value = "enabled",havingValue = "true"),当配置文件中cn.sp.enabled=true时有效。

下面列举SpringBoot中的所有@Conditional注解及作用

@ConditionalOnBean:当容器中有指定的Bean的条件下
@ConditionalOnClass:当类路径下有指定的类的条件下
@ConditionalOnExpression:基于SpEL表达式作为判断条件
@ConditionalOnJava:基于JVM版本作为判断条件
@ConditionalOnJndi:在JNDI存在的条件下查找指定的位置
@ConditionalOnMissingBean:当容器中没有指定Bean的情况下
@ConditionalOnMissingClass:当类路径下没有指定的类的条件下
@ConditionalOnNotWebApplication:当前项目不是Web项目的条件下
@ConditionalOnProperty:指定的属性是否有指定的值
@ConditionalOnResource:类路径下是否有指定的资源
@ConditionalOnSingleCandidate:当指定的Bean在容器中只有一个,或者在有多个Bean的情况下,用来指定首选的Bean
@ConditionalOnWebApplication:当前项目是Web项目的条件下

2.5 创建 spring.factories

resources/META-INF/ 文件夹下创建spring.factories文件,内容如下:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=cn.sp.autoconfigure.StarterAutoConfigure

右边的就是自动配置类的类路径。

三、测试

  1. 执行mvn install命令打包到本地
  2. 在另外一个项目添加依赖
<dependency>
    <groupId>cn.sp</groupId>
    <artifactId>example-spring-boot-starter</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

然后可以看到jar包的结构图如下:
image

  1. application.properties文件添加如下内容
cn.sp.enabled=true
cn.sp.config=fdafdf,ss1,DSDS,DDD
  1. 编写测试类并启动
@RunWith(SpringRunner.class)
@SpringBootTest
public class MySpringbootApplicationTests {

    @Autowired
    StarterService starterService;

    @Test
    public void contextLoads() {
        String[] strings = starterService.split(",");
        for (int i = 0; i < strings.length; i++) {
            System.out.println(strings[i]);
        }
    }
}
  1. 运行结果如下则表示成功。
MySpringbootApplicationTests in 10.977 seconds (JVM running for 13.035)
fdafdf
ss1
DSDS
DDD
[Thread-4] INFO o.s.w.c.s.GenericWebApplicationContext - Closing org.springframework.web.context.support.GenericWebApplicationContext@51f49060: 

四、原理

  • 在应用程序启动过程中,Spring Boot使用SpringFactoriesLoader类加载器查找org.springframework.boot.autoconfigure.EnableAutoConfiguration关键字对应的 Java 配置文件。Spring Boot会遍历在各个jar包中META-INF目录下的spring.factories文件,构建成一个配置文件链表。
  • 根据spring.factories配置加载AutoConfigure
  • 根据 @Conditional注解的条件,进行自动配置并将Bean注入Spring Context中。

参考:

标签:cn,spring,sp,boot,编写,config,public,Starter,SpringBoot
From: https://www.cnblogs.com/lin546/p/16926365.html

相关文章