起步依赖

上一篇笔记中,我们深入学习和分析了SpringBoot的配置文件定义和自动配置的原理,而Starter(起步依赖)是SpringBoot的另一个核心特性,我们知道Spring框架的生态非常强大,起步依赖结合SpringBoot的自动配置机制,我们很容易实现一些开箱即用的特性。

引入起步依赖

一般来说,起步依赖都是以类似spring-boot-starter-xxx的格式命名的,极少数可能特立独行的写为xxx-spring-boot-starter,但只要内部遵循了SpringBoot的自动配置规则,它就是一个合格的起步依赖。

使用Spring Initializr创建工程时,我们可以直接在列表中选择起步依赖;除此之外,创建完工程后我们也可以在工程pom.xml中增删起步依赖。

自定义起步依赖

理解起步依赖最好的方式就是自己编写一个,实际开发中如果需要对某些框架进行SpringBoot集成,也需要我们掌握自定义起步依赖的知识。

pom.xml

我们自己编写起步依赖,最好也遵循spring-boot-starter-xxx的命名格式。起步依赖中,我们应使用spring-boot-starter-parent作为父POM来继承默认配置和依赖版本管理。另外,还需要添加spring-boot-configuration-processor依赖,它用于生成配置元数据(spring-configuration-metadata.json)以支持用户使用我们的起步依赖时具备IDE的自动提示。此外,为了开发方便,我们还引入了Lombok的依赖,实际开发中我们可根据个人喜好选择。

<?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 https://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>3.5.9</version>
        <relativePath/>
    </parent>

    <groupId>com.gacfox.demo</groupId>
    <artifactId>spring-boot-starter-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <java.version>21</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

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

注册Bean

这里假设我们的需求是这样的:Starter中注册一个名为DemoClient的Spring Bean到IoC容器,供用户注入到应用程序的其它地方。引入Starter的应用支持在application.properties中编写2个配置,demo.server-hostdemo.server-port,例子如下。

demo.server-host=127.0.0.1
demo.server-port=8080

下面是Starter工程的目录结构。

src
└── main
    ├── java
    │   └── com
    │       └── gacfox
    │           └── demo
    │               ├── DemoAutoConfiguration.java
    │               ├── DemoClient.java
    │               └── DemoProperties.java
    └── resources
        └── META-INF
            └── spring
                └── org.springframework.boot.autoconfigure.AutoConfiguration.imports

DemoProperties.java

package com.gacfox.demo;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "demo")
public class DemoProperties {
    private String serverHost;
    private int serverPort;
}

DemoClient.java

package com.gacfox.demo;

public class DemoClient {
    private final String serverHost;
    private final int serverPort;

    public DemoClient(DemoProperties properties) {
        this.serverHost = properties.getServerHost();
        this.serverPort = properties.getServerPort();
    }

    public void getData() {
        System.out.println("Got data from " + serverHost + ":" + serverPort);
    }
}

DemoAutoConfiguration.java

package com.gacfox.demo;

import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableConfigurationProperties(DemoProperties.class)
public class DemoAutoConfiguration {
    @Bean
    public DemoClient demoClient(DemoProperties properties) {
        return new DemoClient(properties);
    }
}

META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

com.gacfox.demo.DemoAutoConfiguration

从上面代码可以看出,我们注册Bean的实现方式是这样的:SpringBoot加载AutoConfiguration.imports文件,导入DemoAutoConfiguration,该配置类通过@EnableConfigurationProperties启用DemoProperties的绑定,并创建DemoClientBean,DemoProperties则从application.properties读取了配置。

此时在具体的工程中,我们使用@Autowired就可以依赖注入DemoClient这个Bean了。另外,由于我们引入了spring-boot-configuration-processor这个包,Starter工程在实际打包时会生成一个META-INF/spring-configuration-metadata.json,它是application.properties的约束文件,IDE(如Eclipse)等能够读取这个配置文件并生成自动提示。当然,你也可以手动编写spring-configuration-metadata.json来增强提示,格式参考自动生成的文件即可。

作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。