一、什么是 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
右边的就是自动配置类的类路径。
三、测试
- 执行
mvn install
命令打包到本地 - 在另外一个项目添加依赖
<dependency>
<groupId>cn.sp</groupId>
<artifactId>example-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
然后可以看到jar包的结构图如下:
- 在
application.properties
文件添加如下内容
cn.sp.enabled=true
cn.sp.config=fdafdf,ss1,DSDS,DDD
- 编写测试类并启动
@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]);
}
}
}
- 运行结果如下则表示成功。
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