6.1 starters 原理

  • 启动器 stater 是什么
    • 启动器是一个空 jar 文件,仅提供辅助性依赖管理(即依赖导入);
    • 启动器依赖自动配置模块,当在项目中引入某个 stater 时会引起启动器的所有依赖传递;
    • stater 只能用来做依赖导入,需专门来写一个自动配置类模块,他人在使用时只需引入启动器 stater,就能由 stater 自动导入自动配置模块中的依赖;

image.png

  • 启动器的命名规约
    • 官方命名
      • spring-boot-starter-模块名,eg:spring-boot-starter-web、spring-boot-starter-jdbc;
    • 自定义命名
      • 模块名-spring-boot-starter,eg:mybatis-spring-boot-start;
    • 官方和自定义的区别在于,自定义时要将模块名放在前面;
  • 如何自定义 staters
    • 思考这个场景需要使用到的依赖是什么?【需要导入哪些 jar 包】
    • 如何编写自动配置类
    • 如何加载自动配置类 ```java //1. 自动配置类的 springboot 格式约定 @Configuration //指定这个类是一个配置类 @ConditionalOnXXX //在指定条件成立的情况下自动配置类生效 @AutoConfigureAfter //指定自动配置类的顺序 @Bean //给容器中添加组件 @ConfigurationPropertie结合相关xxxProperties类来绑定相关的配置 @EnableConfigurationProperties //让xxxProperties生效加入到容器中 public class XxxxAutoConfiguration { … }

//2. 启动时加载自动配置类 将自动配置类配置在类路径下 META-INF/spring.factories 中,具体可参考 org.springframework.boot.autoconfigure.EnableAutoConfiguration;

  1. <a name="V9gti"></a>
  2. ## 6.2 案例
  3. <a name="2HDNC"></a>
  4. ### 6.2.1 代码实现
  5. - 目录结构(两个 model)
  6. - 第一个为“启动器”模块,作用是在 pom.xml 中导入第二个模块所构建的自动配置项;
  7. - 第二个为“自动配置”模块,在该模块中需实现基本的自动配置类、参数绑定类和注入的 bean 组件等,且为了被调用的项目在启动时扫描并加载,需在类路径下创建 META-INF/spring.properties;
  8. ![image.png](https://cdn.nlark.com/yuque/0/2020/png/611598/1585379119015-6a09978b-4622-410c-8a19-810d9a7760e0.png#align=left&display=inline&height=499&name=image.png&originHeight=499&originWidth=1106&size=47987&status=done&style=none&width=1106)
  9. <a name="hyQ4p"></a>
  10. #### 6.2.1.1 自动配置模块 cyt-spring-boot-stater-autoconfigurer
  11. - **注:在创建时该自动配置模块不需要引入其他的 stater;**
  12. - jar 包依赖
  13. ```java
  14. <?xml version="1.0" encoding="UTF-8"?>
  15. <project xmlns="http://maven.apache.org/POM/4.0.0"
  16. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  17. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  18. <modelVersion>4.0.0</modelVersion>
  19. <parent>
  20. <groupId>org.springframework.boot</groupId>
  21. <artifactId>spring-boot-starter-parent</artifactId>
  22. <version>2.2.1.RELEASE</version>
  23. <relativePath/>
  24. </parent>
  25. // 自动配置模块的引用标识,稍后被 6.2.1.2 创建的启动器模型引入
  26. <groupId>com.cyt.starter</groupId>
  27. <artifactId>cyt-spring-boot-stater-autoconfiguere</artifactId>
  28. <version>1.0-SNAPSHOT</version>
  29. <properties>
  30. <java.version>1.8</java.version>
  31. </properties>
  32. <dependencies>
  33. <!--引入spring‐boot‐starter;所有 starter 的基本配置-->
  34. <dependency>
  35. <groupId>org.springframework.boot</groupId>
  36. <artifactId>spring-boot-starter</artifactId>
  37. </dependency>
  38. <!--可以生成配置类提示文件-->
  39. <dependency>
  40. <groupId>org.springframework.boot</groupId>
  41. <artifactId>spring-boot-configuration-processor</artifactId>
  42. <optional>true</optional>
  43. </dependency>
  44. </dependencies>
  45. </project>
  • HelloServiceAutoConfiguration

    • 实现参数注入的 HelloProperties.class;
    • 属于该场景下的容器组件类 HelloService;

      @Configuration
      @ConditionalOnWebApplication //设置只有在是 web 应用才生效
      @EnableConfigurationProperties(HelloProperties.class) //让配置类生效
      public class HelloServiceAutoConfiguration {
      @Autowired
      HelloProperties helloProperties;
      
      @Bean
      public HelloService helloService(){
         HelloService service = new HelloService();
         service.setHelloProperties(helloProperties);
         return service;
      }
      }
      
  • HelloProperties 类

    @ConfigurationProperties(prefix = "cyt.hello")
    public class HelloProperties {
      private String prefix;
      private String suffix;
    
      public String getPrefix() {
          return prefix;
      }
    
      public void setPrefix(String prefix) {
          this.prefix = prefix;
      }
    
      public String getSuffix() {
          return suffix;
      }
    
      public void setSuffix(String suffix) {
          this.suffix = suffix;
      }
    
      @Override
      public String toString() {
          return "HelloProperties{" +
                  "prefix='" + prefix + '\'' +
                  ", suffix='" + suffix + '\'' +
                  '}';
      }
    }
    
  • HelloService 类

    public class HelloService {
    
      HelloProperties helloProperties;
    
      public String sayHelloCyt(String name){
          return helloProperties.getPrefix() + "-" + name + helloProperties.getSuffix();
      }
    
      public HelloProperties getHelloProperties() {
          return helloProperties;
      }
    
      public void setHelloProperties(HelloProperties helloProperties) {
          this.helloProperties = helloProperties;
      }
    }
    
  • resources/META-INF/spring.factories

    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
      com.cyt.stater.HelloServiceAutoConfiguration
    

    6.2.1.2 启动器模块 cyt-spring-boot-stater

  • 在 pom.xml 中引入 6.2.1.1 定义的自动配置模块

    <?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.cyt.stater</groupId>
      <artifactId>cyt-spring-boot-stater</artifactId>
      <version>1.0-SNAPSHOT</version>
    
      <!--启动器-->
      <dependencies>
          <!--引入自动配置模块-->
          <dependency>
              <groupId>com.cyt.starter</groupId>
              <artifactId>cyt-spring-boot-stater-autoconfiguere</artifactId>
              <version>1.0-SNAPSHOT</version>
          </dependency>
      </dependencies>
    </project>
    

    6.2.1.3 将创建的模块导入 maven 仓库中

    image.png

    6.2.2 测试

    6.2.2.1 jar 包准备

  • 创建项目测试,选择添加 web 场景,因为设置是 web 场景才生效;

  • 在 pom.xml 中引入自定义的 stater ```java <?xml version=”1.0” encoding=”UTF-8”?> 4.0.0

      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>2.2.6.RELEASE</version>
      <relativePath/> <!-- lookup parent from repository -->
    

    com.cyt.stater spring-boot-08-stater-test 0.0.1-SNAPSHOT spring-boot-08-stater-test

    Demo project for Spring Boot 1.8 com.cyt.stater cyt-spring-boot-stater 1.0-SNAPSHOT org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.junit.vintage junit-vintage-engine org.springframework.boot spring-boot-maven-plugin


- 注意查看外部 jar 包依赖是否添加好自定义的 stater

![image.png](https://cdn.nlark.com/yuque/0/2020/png/611598/1585380971238-cf384658-3844-4be6-83b9-8bac9d4856fc.png#align=left&display=inline&height=142&name=image.png&originHeight=142&originWidth=570&size=19551&status=done&style=none&width=570)
<a name="PJSDy"></a>
#### 6.2.2.2 编写一个测试的 controller

- 在 HelloController 中通过发送的 “hello”请求,加载 6.2.1.1 自定义的自动配置类包含的 bean 组件 到容器中,然后调用 helloService 的方法并返回其结果到默认页面;
```java
@RestController
public class HelloController {
    @Autowired
    HelloService helloService;

    @RequestMapping("/hello")
    public String hello(){
        return helloService.sayHelloCyt("ChenYuTing");
    }
}

6.2.2.3 结果

image.png