自定义SpringBoot stater
stater的启动原理
stater-pom引入autoconfigure包
autoconfigure包中的配置使用META-INFO/spring.factories中的“org.springframework.boot.autoconfigure.EnableAutoConfiguration”的值,使得项目启动时加载指定的自动配置类
这里的autoconfigure指的是我们通过can-spring-boot-stater依赖的can-spring-boot-stater-autoconfigure
自定义的stater步骤
1.创建can-spring-boot-stater删除多余的配置和文件夹,目录如下:
pom文件引入can-spring-boot-stater-autoconfigure的坐标
1 2 3 4 5
| <dependency> <groupId>com.can</groupId> <artifactId>can-spring-boot-stater-autoconfigure</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency>
|
2.使用spring initializr创建can-spring-boot-stater-autoconfigure,选择Spring web和Spring Configuration Processor
pml文件如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| <?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 https://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.7.11</version> <relativePath/> </parent> <groupId>com.can</groupId> <artifactId>can-spring-boot-stater-autoconfigure</artifactId> <version>0.0.1-SNAPSHOT</version> <name>can-spring-boot-stater-autoconfigure</name> <description>can-spring-boot-stater-autoconfigure</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <version>2.3.4.RELEASE</version> <optional>true</optional> </dependency> </dependencies>
</project>
|
3.创建CanProperties.class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| @ConfigurationProperties(prefix = "can") public class CanProperties {
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; } }
|
4.定义业务类CanService
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public class CanService {
private CanProperties canProperties;
public CanProperties getCanProperties() { return canProperties; }
public void setCanProperties(CanProperties canProperties) { this.canProperties = canProperties; }
public String sayHello(String name){ return canProperties.getPrefix()+"--"+name+"--"+canProperties.getSuffix(); } }
|
5.创建自动配置类并添加到IOC中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @Configuration @ConditionalOnWebApplication @EnableConfigurationProperties(CanProperties.class) public class CanAutoConfiguration {
@Autowired private CanProperties canProperties;
@Bean @ConditionalOnMissingBean(CanService.class) public CanService canService(){ CanService canService = new CanService(); canService.setCanProperties(canProperties); return canService; } }
|
6.在resource目录下创建META-INF/spring.factories文件
1 2 3
| org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.can.autoconfigure.CanAutoConfiguration
|
7.clean can-spring-boot-stater-autoconfigure 项目,然后install ,can-spring-boot-stater-autoconfigure重复这个步骤
8.新建一个demo,引入自定义stater坐标,并设置属性
1 2 3 4 5 6
| <dependency> <groupId>com.can</groupId> <artifactId>can-spring-boot-stater</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
|
1 2
| can.prefix=nihao can.suffix=fitting
|
总结:
我们在测试Controller中使用了@Autowired去自动导入了我们在hello-spring-boot-starter-autoconfigure定义的业务类,在自动导入之前,springboot就已经扫描完所有导入starter的类,最终会扫描到每个starter类依赖的xxxAutoConfigure下的META-INF/spring.factories,通过该文件获取到xxxAutoConfiguration的全类限定名,就会去加载我们写在xxx-spring-boot-xxxAutoConfigure项目下的xxxAutoConfiguration类,也就是我们前面定义的CanAutoConfiguration,通过判断是否执行创建CanService,从而决定是否对CanProperties.class进行下一步操作(开启与对应properties的前缀进行绑定以及添加到IOC容器)
在HelloServiceAutoConfiguration中使用**@ConditionalOnMissingBean(CanService.class),如果我们在当前容器中也就是测试项目容器有CanService.class的存在,也就不会去执行CanServiceAutoConfiguration**下的某个对应方法