从零编写Spring Boot Starter

2020-03-17 16:08:21来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

从零编写Spring Boot Starter

从零实现Spring Boot的starter编写

Spring Boot为广大开发人员提供了便利。
本文将介绍如何编写Starter,以便开发人员复用自己或项目组的代码。

代码下载地址:https://gitee.com/jxd134/Spring-Boot-Greeter-Starter.git

1 新建项目

项目基于Maven构建,包含以下三个模块:

  • greeter-library:封装工具类;
  • greeter-spring-boot-autoconfigure: 完成自动化配置;
  • greeter-spring-boot-starter: 提供给用户使用.

主项目pom.xml中内容如下所示(省略部分内容):

    <groupId>org.example</groupId>
    <artifactId>spring-boot-custom-starter</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>pom</packaging>

    <modules>
        <module>greeter-library</module>
        <module>greeter-spring-boot-autoconfigure</module>
        <module>greeter-spring-boot-starter</module>
    </modules>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot</artifactId>
            <version>2.2.5.RELEASE</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven-compiler-plugin.version>3.8.0</maven-compiler-plugin.version>
    </properties>

需要注意,父项目中打包方式需要设置为pom,此外Spring Boot版本需要明确(可根据项目组规定确定).

2 工具类(greeter-library)

项目pom.xml中内容如下所示(省略部分内容):

    <parent>
        <artifactId>spring-boot-custom-starter</artifactId>
        <groupId>org.example</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>greeter-library</artifactId>
    <name>greeter-library</name>
    <version>0.0.1-SNAPSHOT</version>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven-compiler-plugin.version}</version>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

此处创建项目启动欢迎代码示例(仅作为举例使用):

    public String greet(LocalDateTime localDateTime) {

        String name = greetingConfig.getProperty(USER_NAME);
        int hourOfDay = localDateTime.getHour();

        if (hourOfDay >= 5 && hourOfDay < 12) {
            return String.format("Hello %s, %s", name, greetingConfig.get(MORNING_MESSAGE));
        } else if (hourOfDay >= 12 && hourOfDay < 17) {
            return String.format("Hello %s, %s", name, greetingConfig.get(AFTERNOON_MESSAGE));
        } else if (hourOfDay >= 17 && hourOfDay < 20) {
            return String.format("Hello %s, %s", name, greetingConfig.get(EVENING_MESSAGE));
        } else {
            return String.format("Hello %s, %s", name, greetingConfig.get(NIGHT_MESSAGE));
        }
    }

    public String greet() {
        return greet(LocalDateTime.now());
    }

此处,基本完成工具类模块代码编写.

3 自动化配置(greeter-spring-boot-autoconfigure)

3.1 配置原理

工具类已完成封装,此时需要完成工具类的自动化配置代码编写。
Spring Boot项目启动时,会扫描classpath下的spring.factories文件(位于META-INF文件夹),根据配置信息加载classpath下的相应配置类。

此处,以spring.boot.autoconfigure依赖下的spring.factories作为示例:

spring.factories文件中,自动化配置依赖如下所示:

3.2 创建配置类

配置类代码如下所示:

@ConfigurationProperties(prefix = "greeter")
public class GreeterProperties {

    private String userName;
    private String morningMessage;
    private String afternoonMessage;
    private String eveningMessage;
    private String nightMessage;

    // 省略get/set函数
}

@Configuration
@ConditionalOnClass(Greeter.class)
@EnableConfigurationProperties(GreeterProperties.class)
public class GreeterAutoConfiguration {

    @Autowired
    private GreeterProperties greeterProperties;

    @Bean
    @ConditionalOnMissingBean
    public GreetingConfig greeterConfig() {

        String userName = greeterProperties.getUserName() == null ? System.getProperty("user.name") : greeterProperties.getUserName();
        String morningMessage = greeterProperties.getMorningMessage() == null ? "Good Morning" : greeterProperties.getMorningMessage();
        String afternoonMessage = greeterProperties.getAfternoonMessage() == null ? "Good Afternoon" : greeterProperties.getAfternoonMessage();
        String eveningMessage = greeterProperties.getEveningMessage() == null ? "Good Evening" : greeterProperties.getEveningMessage();
        String nightMessage = greeterProperties.getNightMessage() == null ? "Good Night" : greeterProperties.getNightMessage();

        GreetingConfig greetingConfig = new GreetingConfig();
        greetingConfig.put(USER_NAME, userName);
        greetingConfig.put(MORNING_MESSAGE, morningMessage);
        greetingConfig.put(AFTERNOON_MESSAGE, afternoonMessage);
        greetingConfig.put(EVENING_MESSAGE, eveningMessage);
        greetingConfig.put(NIGHT_MESSAGE, nightMessage);
        return greetingConfig;
    }

    @Bean
    @ConditionalOnMissingBean
    public Greeter greeter(GreetingConfig greetingConfig) {
        return new Greeter(greetingConfig);
    }
}

以上是模块主要代码,主要分为配置信息类,以及自动化配置类:

  1. GreeterProperties:从项目配置文件中读取配置信息,此处使用ConfigurationProperties读取前缀为greeter的配置信息;
  2. GreeterAutoConfiguration:依赖于Greeter类,当加载了Greeter类时,Spring会加载GreeterAutoConfiguration中定义的bean。

ConditionalOnMissingBean: 被修饰的bean,如果IOC中不存在,则会加载至IOC

3.3 配置文件

META-INF文件夹中添加spring.factories文件,填写自动化配置类的全限定名,如下所示:

org.springframework.boot.com.example.greeter.autoconfigure.EnableAutoConfiguration=\
com.example.greeter.autoconfigure.GreeterAutoConfiguration

4 Starter成品(greeter-spring-boot-starter)

当前模块仅需要添加pom.xml,就可以将starter完美的呈现给用户:

    <parent>
        <artifactId>spring-boot-custom-starter</artifactId>
        <groupId>org.example</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <artifactId>greeter-spring-boot-starter</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>greeter-spring-boot-starter</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <greeter.version>0.0.1-SNAPSHOT</greeter.version>
        <spring-boot.version>2.2.5.RELEASE</spring-boot.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <version>${spring-boot.version}</version>
        </dependency>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>greeter-spring-boot-autoconfigure</artifactId>
            <version>${greeter.version}</version>
        </dependency>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>greeter-library</artifactId>
            <version>${greeter.version}</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven-compiler-plugin.version}</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

引入Spring Boot依赖,以及封装工具模块和自动化配置模块(当前模块类似于代理)。
执行mvn install命令后,starter相关jar包存储至maven本地仓库供用户使用。

因为需要打包,因此引入maven-compiler-plugin

5 示例

示例较为简单,仅需在pom.xml文件中引入依赖如下所示:

        <dependency>
            <groupId>org.example</groupId>
            <artifactId>greeter-spring-boot-starter</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

即可实现自制starter的引入(需要注意starter的Spring Boot版本号匹配)。

本文参照https://www.baeldung.com/spring-boot-custom-starter一文编写。
PS:
如果您觉得我的文章对您有帮助,请关注我的微信公众号,谢谢!
程序员打怪之路


原文链接:https://www.cnblogs.com/jason1990/p/12513923.html
如有疑问请与原作者联系

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:java 多态成员函数(静态与非静态)、成员变量特点

下一篇:Java的基础知识