6.1 starters 原理
- 启动器 stater 是什么
- 启动器是一个空 jar 文件,仅提供辅助性依赖管理(即依赖导入);
- 启动器依赖自动配置模块,当在项目中引入某个 stater 时会引起启动器的所有依赖传递;
- stater 只能用来做依赖导入,需专门来写一个自动配置类模块,他人在使用时只需引入启动器 stater,就能由 stater 自动导入自动配置模块中的依赖;
- 启动器的命名规约
- 官方命名
- 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;
<a name="V9gti"></a>
## 6.2 案例
<a name="2HDNC"></a>
### 6.2.1 代码实现
- 目录结构(两个 model)
- 第一个为“启动器”模块,作用是在 pom.xml 中导入第二个模块所构建的自动配置项;
- 第二个为“自动配置”模块,在该模块中需实现基本的自动配置类、参数绑定类和注入的 bean 组件等,且为了被调用的项目在启动时扫描并加载,需在类路径下创建 META-INF/spring.properties;
![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)
<a name="hyQ4p"></a>
#### 6.2.1.1 自动配置模块 cyt-spring-boot-stater-autoconfigurer
- **注:在创建时该自动配置模块不需要引入其他的 stater;**
- jar 包依赖
```java
<?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.2.1.RELEASE</version>
<relativePath/>
</parent>
// 自动配置模块的引用标识,稍后被 6.2.1.2 创建的启动器模型引入
<groupId>com.cyt.starter</groupId>
<artifactId>cyt-spring-boot-stater-autoconfiguere</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--引入spring‐boot‐starter;所有 starter 的基本配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!--可以生成配置类提示文件-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</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 仓库中
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");
}
}