手写spring-boot-start

  • Post author:
  • Post category:其他


在手写start之前,先思考下三个点:

1. 回忆了解下Springboot装载过程

2. 编写spring-boot-start的目的

3. 编写spring-boot-start的步骤

SpringBoot装载过程

装载过程,我们从两个点出发:

1. SpringApplication.run()方法(应该很熟悉)

2. @SpringBootApplication

源码的分析网上有很多,总结一张思路图如下:

编写spring-boot-start的目的

通俗的理解:1. 承上启下,即对原有的常用中间件的常见配置,进行通用配置、包装、扩展等封装配置,已达到下层服务使用更加方便(eg: DB、MQ多数据源支持等)。2. 编写符合多种业务的通用组件进行包装,以便下层更好的使用。(eg:sharding-jdbc-spring-boot-starter、mybatis-plus-boot-starter,以及SpringBoot常用的jdbc\redis等中间件start包等等)

编写spring-boot-start的步骤

1. 编写会用到的Properties类

@Data
@ConfigurationProperties(prefix = "hello")
public class HelloProperties {

  private boolean enableHello;

  private String msg;

  private int count;

  private List<Person> personList;

  @Data
  public static class Person{

    private String name;

    private int sex;

    private int age;

  }

}

2. 编写配置类(自动装载)

@Configuration
@ConditionalOnWebApplication
@EnableConfigurationProperties(HelloProperties.class)
public class HelloAutoConfigure {

  @Bean
  @ConditionalOnMissingBean(HelloService.class)
  public HelloService helloService(){
    return new DefaultHelloServiceImpl();
  }

}

3. 编写spring.factories(/resource/META-INF/spring.factories)

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.rhb.boot.autoconfigure.HelloAutoConfigure

4. 编写元数据文档spring-configuration-metadata.json(同3)

{
  "hints":[{
    "name":"hello.msg",
    "values":[{
      "value":"你好",
      "description":"中文方式打招呼"
    },{
      "value":"Hi",
      "description":"英文方式打招呼"
    }]
  }],
  "groups":[
    {
      "sourceType": "com.rhb.boot.prop.HelloProperties",
      "name": "hello",
      "type": "com.rhb.boot.prop.HelloProperties"
    }],
  "properties":[
    {
      "sourceType": "com.rhb.boot.prop.HelloProperties",
      "name": "hello.msg",
      "type": "java.lang.String",
      "description": "打招呼的内容",
      "defaultValue": "Worlds"
    }]
}

pom文件

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

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

    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.16.18</version>
      <scope>provided</scope>
    </dependency>

  </dependencies>
注解 作用
@ConditionalOnBean 当容器中有指定的Bean的条件下
@ConditionalOnMissingBean 当容器中没有指定Bean的情况下
@ConditionalOnClass 当类路径下有指定的类的条件下
@ConditionalOnMissingClass 当类路径下没有指定的类的条件下
@ConditionalOnWebApplication 当前项目是Web项目的条件下
@ConditionalOnNotWebApplication 当前项目不是Web项目的条件下
@ConditionalOnJndi 在JNDI存在的条件下查找指定的位
@ConditionalOnJava 基于JVM版本作为判断条件
@ConditionalOnExpression 基于SpEL表达式作为判断条件
@ConditionalOnResource 类路径下是否有指定的资源
@ConditionalOnSingleCandidate 当指定的Bean在容器中只有一个,或者在有多个Bean的情况下,用来指定首选的Bean
@ConditionalOnProperty 指定的属性是否有指定的值



版权声明:本文为weixin_38289303原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。