0%

自己写一个spring-boot-start

Spring Boot由众多Starter组成,随着版本的推移Starter家族成员也与日俱增。在传统Maven项目中通常将一些层、组件拆分为模块来管理, 以便相互依赖复用,在Spring Boot项目中我们则可以创建自定义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>

  <groupId>com.majm</groupId>
  <artifactId>sample-spring-boot-starter</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <name>sample-spring-boot-starter</name>

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

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <dependencies>

    <!-- @ConfigurationProperties annotation processing (metadata for IDEs)
                 生成spring-configuration-metadata.json类,需要引入此类-->
    <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-autoconfigure</artifactId>
    </dependency>
    
  </dependencies>
</project>

注意 依赖 spring-boot-configuration-processor 是为了在编译时生成 spring-configuration-metadata.json文件,此文件主要是给 IDE 使用,用于提示使用。
example: 如在Intellij idea中,当配置此 jar 相关配置属性在application.yml,你可以用cmd + 鼠标左键,IDE会跳转到你配置此属性的类中。

这里说一下 artifactId 命名问题, spring 官方Start 通用命名规则为 spring-boot-starter-{name}
spring 官方建议非官方 start 命名规范 {name}-spring-boot-starter

2. 编写 Service

/**
 * 业务类 </br>
 *
 * @author majunmin
 * @description
 * @datetime 2019-07-04 17:59
 * @since
 */
@AllArgsConstructor
public class ExampleService {

    private String name;

    private String desc;

    public String desc(){
        return name + ":" + desc;
    }

}

3. 编写属性类

/**
 * 属性类 </br>
 *
 * @author majunmin
 * @description
 * @datetime 2019-07-04 17:53
 * @since
 */
@Getter
@Setter
@ConfigurationProperties("com.service")
public class ExampleProperties {

    private String name;

    private String desc;

}

4. 编写自动配置类

/**
 * 自动配置类 </br>
 *
 * 1. @ConditionalOnClass,当classpath下发现该类的情况下进行自动配置。
 * 2. @ConditionalOnMissingBean,当Spring Context中不存在该Bean时。
 * 3. @ConditionalOnProperty(prefix = "example.service",value = "enabled",havingValue = "true"),当配置文件中example.service.enabled=true时。
 *
 * @author majunmin
 * @description
 * @datetime 2019-07-04 17:57
 * @since
 */
@Configuration
@ConditionalOnClass(ExampleService.class)
@EnableConfigurationProperties(ExampleProperties.class)
public class ExampleAutoConfig {

    private final ExampleProperties exampleProperties;

    @Autowired
    public ExampleAutoConfig(ExampleProperties exampleProperties) {
        this.exampleProperties = exampleProperties;
    }


    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(prefix = "example.service", value = "enabled", havingValue = "true")
    ExampleService exampleService(){
        return new ExampleService(exampleProperties.getName(), exampleProperties.getDesc());
    }


}

5. 添加spring.factories

在resources/META-INF/下创建 spring.factories 文件

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.majm.config.ExampleAutoConfig

ok 完成, 执行 mvn clean install -DskipTests,打包安装到本地

6. Test

好了 来测试一下。

另外创建一个SpringBoot工程,在maven中引入这个starter依赖, 然后在单元测试中引入这个Service看看效果。

  1. pom文件 引入依赖
    ···xml

    com.majm sample-spring-boot-starter 1.0.0-SNAPSHOT ···
  2. application.yml 中 添加属性

    com.service:
      enabled: true
      name: aaa
      desc: bbb

编写 Controller

@Autowired
private ExampleService exampleService;

@GetMapping("/test")
public Object getUser() {
    return exampleService.desc();
}

返回结果如下
result

OK!

总结

总结下Starter的工作原理:

  1. Spring Boot在启动时扫描项目所依赖的JAR包,寻找包含 spring.factories 文件的JAR包
  2. 根据 spring.factories 配置加载AutoConfigure类
  3. 根据 @Conditional 注解的条件,进行自动配置并将Bean注入Spring Context

代码地址

Github

欢迎关注我的其它发布渠道