Write Spring Boot Starter from scratch

Spring Boot provides convenience for developers.
This article describes how to write Starter so that developers can reuse their own or project group's code.

Code download address: https://gitee.com/jxd134/Spring-Boot-Greeter-Starter.git

1 new project

The project is built on Maven and consists of the following three modules:

  • Greeter Library: encapsulation tool class;
  • Greeter spring boot autoconfigure: complete automatic configuration;
  • Greeter spring boot starter: provided to users

The main project pom.xml is as follows (some contents are omitted):

    <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>

It should be noted that the packaging method in the parent project needs to be set to pom, and the version of Spring Boot needs to be clear (it can be determined according to the regulations of the project team)

2 tool class (greeter Library)

The contents of project pom.xml are as follows (some contents are omitted):

    <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>

Create a sample project launch welcome code here (for example only):

    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());
    }

Here, the basic completion of tool module code

3. Automatic configuration (greeter spring boot autoconfigure)

3.1 configuration principle

The tool class has finished encapsulation. At this time, you need to complete the automatic configuration code writing of the tool class.
When the Spring Boot project starts, it will scan the spring.factories file under classpath (located in the META-INF folder), and load the corresponding configuration classes under classpath according to the configuration information.

Here, take spring.factories under the dependency of spring.boot.autoconfigure as an example:

In the spring.factories file, the automation configuration depends on the following:

3.2 create configuration class

The configuration class code is as follows:

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

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

    // Omit get/set function
}

@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);
    }
}

The above is the main code of the module, which is mainly divided into configuration information class and automatic configuration class:

  1. GreeterProperties: read the configuration information from the project configuration file. Here, use ConfigurationProperties to read the configuration information prefixed with greeter;
  2. GreeterAutoConfiguration: depends on the Greeter class. When the Greeter class is loaded, Spring will load the bean s defined in the GreeterAutoConfiguration.

ConditionalOnMissingBean: the decorated bean will be loaded into IOC if it does not exist in IOC.

3.3 configuration file

Add the spring.factories file to the META-INF folder, and fill in the fully qualified name of the automation configuration class, as shown below:

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

4. Starter (greeter spring boot starter)

The current module only needs to add pom.xml to present the starter to the user perfectly:

    <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>

Introduce Spring Boot dependency, as well as encapsulation tool module and automation configuration module (current module is similar to agent).
After the mvn install command is executed, the jar packages related to the starter are stored in the maven local warehouse for users to use.

Because packaging is needed, Maven compiler plugin is introduced.

5 example

The example is relatively simple, just introduce dependency in pom.xml file as follows:

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

You can introduce a self-made starter (note that the Spring Boot version number of the starter matches).

This article is written with reference to https://www.baeldung.com/spring-boot-custom-starter.
PS:
If you think my article is helpful to you, please pay attention to my WeChat official account. Thank you!

Keywords: Java Spring Maven snapshot xml

Added by ace_lovegrove on Tue, 17 Mar 2020 17:41:45 +0200