实现SpringBootStarter(二):实现简单的SpringBootStarter

1,178 阅读2分钟

上一篇 实现SpringBootStarter(一): SpringBoot Auto Configuration 流程介绍了SpringBoot Starter 如何实现配置的自动扫描(Auto Configuration)的步骤:

  1. 定义 Properties 配置类

  2. 定义 AutoConfiguration 类

    • @Configuration 注解修饰
    • @EnableConfigurationProperties(Properties.class) 加载第一步定义的配置文件
    • @Bean 定义需要 Spring 管理的 Bean 对象
  3. META-INF/spring.factories 配置自动加载信息

# 第二步定义的 AutoConfiguration 类的完整包路径
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.***.AutoConfiguration

1.1 命名规则

SpringBoot提供的starter以spring-boot-starter-xxx的方式命名的。官方建议自定义的starter使用xxx-spring-boot-starter命名规则。以区分SpringBoot生态提供的starter。

本节就根据这几步实现一个简单的 SpringBoot Starter。 本例实现一个 my-spring-boot-starter 包。

1. 创建maven工程

pom文件如下:

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

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.0.RELEASE</version>
    </parent>

    <groupId>com.omg</groupId>
    <artifactId>my-spring-boot-starter</artifactId>
    <version>1.0-SNAPSHOT</version>
    <name>my-spring-boot-starter</name>
    <description>我自己实现的SpringBootStarter</description>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <java.version>1.8</java.version>
    </properties>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
    </dependencies>

</project>

2. 实现 SpringBoot Starter

目录结构如下: image.png

2.1 定义 Properties 配置类

package com.omg.starter.my.properties;

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

/**
 * @description: 配置文件
 * @Author: omg
 */

@ConfigurationProperties(
        prefix = "my"
)
public class MyStarterProperties {
    private String name;
    private String age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
}

2.2 定义 AutoConfiguration 类

在定义 AutoConfiguration 之前,为了该 AutoConfiguration 能够验证,先定义一个简单的Service。

2.2.1 定义 Service

package com.omg.starter.my.service;

import com.omg.starter.my.properties.MyStarterProperties;

/**
 * @description: 实现一个简单的 Service
 * @Author: omg
 */
public class MyStarterService {
    private final MyStarterProperties properties;

    public MyStarterService(MyStarterProperties properties) {
        this.properties = properties;
    }

    public String getMyInfo(){
        return String.format("my name is %s, age %s", properties.getName(), properties.getAge());
    }
}

2.2.2 定义 AutoConfiguration 类

  • @Configuration 定义修饰的类为配置类
  • @ConditionalOnProperty 定义Bean生效的条件为配置文件中 my.enable=true时生效,本类才会继续加载,否则不再加载
  • @EnableConfigurationProperties 告诉SpringBoot 加载配置类,也就是2.1节定义的MyStarterProperties。
package com.omg.starter.my.properties;

import com.omg.starter.my.service.MyStarterService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @description: Spring Boot Auto Configuration 自动加载配置
 * @Author: omg
 */

@Configuration
@ConditionalOnProperty(prefix = "my", name = "enable", havingValue = "true")
@EnableConfigurationProperties(MyStarterProperties.class)
public class MyStarterAutoConfiguration {
    @Autowired
    private MyStarterProperties properties;

    @Bean
    public MyStarterService myStarterService(){
        return new MyStarterService(properties);
    }
}

2.3 META-INF/spring.factories 配置自动加载信息

spring.factories 定义 SpringBoot 启动时需要自动加载的项,本例中为 MyStarterAutoConfiguration。

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.omg.starter.my.properties.MyStarterAutoConfiguration

至此一个完整的SpingBoot Starer 已经实现完成,接下来就是验证环节。

3. 验证

  1. 创建SpringBoot项目并引入上面实现的 my-spring-boot-starter
<dependency>
    <groupId>com.omg</groupId>
    <artifactId>my-spring-boot-starter</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>
  1. 配置文件
my.enable=true
my.name=omg
my.age=18
  1. 实现 Controller 验证:在 Controller 里面引入 MyStarterService。
package com.omg.test.controller;

import com.omg.starter.my.service.MyStarterService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyStarterTestController {

    @Autowired
    MyStarterService myStarterService;

    @GetMapping("info")
    public String myInfo(){
        return myStarterService.getMyInfo();
    }
}
  1. 验证

image.png