起步(Starter)依赖是SpringBoot的一个核心特性。我们知道Spring框架的生态非常强大,起步依赖结合SpringBoot的自动配置,我们很容易实现一些开箱即用的特性。
起步依赖都是以类似spring-boot-starter-xxx
的格式命名的。
使用Spring Initializr创建工程时,我们可以直接在列表中选择起步依赖;除此之外,创建完工程后我们也可以在工程pom.xml
中增删起步依赖。
理解起步依赖最好的方式就是自己编写一个,实际开发中如果对一些框架进行SpringBoot集成,也需要我们掌握自定义起步依赖的知识。
我们自己编写起步依赖,也要遵循spring-boot-starter-xxx
的格式。两个必要的依赖是spring-boot-starter
和spring-boot-configuration-processor
,前者包含了Spring核心框架中一些必备的类,后者用于生成SpringBoot的application.properties
配置文件的约束文件。
<?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>com.gacfox.demo</groupId>
<artifactId>spring-boot-starter-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.7.8</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>2.7.8</version>
</dependency>
</dependencies>
</project>
这里假设我们的需求是这样的:我们的Starter注册了一个DemoClient
到Spring容器,供注入到应用程序的其它地方。引用Starter的应用支持在application.properties
中编写2个配置server-host
和server-port
,例如:
demo.server-host=127.0.0.1
demo.server-port=8080
下面是Start工程的例子代码。
src
|_main
|_com.gacfox.demo
|_DemoAutoConfiguration
|_DemoClient
|_DemoClientConfigure
|_resources
|_META-INF
|_spring.factories
DemoAutoConfiguration.java
package com.gacfox.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableConfigurationProperties({DemoClientConfigure.class})
public class DemoAutoConfiguration {
private DemoClientConfigure demoClientConfigure;
@Autowired
public void setDemoClientConfigure(DemoClientConfigure demoClientConfigure) {
this.demoClientConfigure = demoClientConfigure;
}
@Bean
public DemoClient demoClient() {
return new DemoClient(demoClientConfigure);
}
}
DemoClient.java
package com.gacfox.demo;
public class DemoClient {
private String serverHost;
private Integer serverPort;
public DemoClient(DemoClientConfigure demoClientConfigure) {
serverHost = demoClientConfigure.getServerHost();
serverPort = demoClientConfigure.getServerPort();
}
public void getData() {
System.out.println("Got data from " + serverHost + ":" + serverPort);
}
}
DemoClientConfigure.java
package com.gacfox.demo;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "demo")
public class DemoClientConfigure {
private String serverHost;
private Integer serverPort;
public String getServerHost() {
return serverHost;
}
public void setServerHost(String serverHost) {
this.serverHost = serverHost;
}
public Integer getServerPort() {
return serverPort;
}
public void setServerPort(Integer serverPort) {
this.serverPort = serverPort;
}
}
spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.gacfox.demo.DemoAutoConfiguration
从上面代码可以看出,我们注册Bean的是这样实现的:首先由SpringBoot加载起步依赖的spring.factories
配置,并加载DemoAutoConfiguration
,再由该配置类加载DemoClientConfigure
和DemoClient
,其中DemoClientConfigure
用于读取application.properties
配置文件,而DemoClient
就是具体的业务逻辑实现。
此时在具体的工程中,我们使用@Autowired
就可以依赖注入DemoClient
这个Bean了。另外,由于我们引入了spring-boot-configuration-processor
这个包,Starter工程在实际打包时会生成一个META-INF/spring-configuration-metadata.json
,它是application.properties
的约束文件,IDE(如Eclipse)等能够读取这个配置文件并生成自动提示。
当然,这里我们的spring-configuration-metadata.json
是自动生成的,其实我们也可以手动编写该文件,具体参考自动生成的格式即可,这里就不多介绍了。