從零編寫Spring Boot Starter

Spring Boot爲廣大開發人員提供了便利。
本文將介紹如何編寫Starter,以便開發人員複用本身或項目組的代碼。java

代碼下載地址:https://gitee.com/jxd134/Spring-Boot-Greeter-Starter.gitgit

1 新建項目

項目基於Maven構建,包含如下三個模塊:程序員

  • greeter-library:封裝工具類;
  • greeter-spring-boot-autoconfigure: 完成自動化配置;
  • greeter-spring-boot-starter: 提供給用戶使用.

主項目pom.xml中內容以下所示(省略部份內容):spring

<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版本須要明確(可根據項目組規定肯定).apache

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>

此處建立項目啓動歡迎代碼示例(僅做爲舉例使用):maven

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

此處,以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:
若是您以爲個人文章對您有幫助,請關注個人微信公衆號,謝謝!
程序員打怪之路

相關文章
相關標籤/搜索