在SpringBoot 项目中有很多模块都是由starter模块组成的,为实现一些特定的功能,我们可以自定义Spring-Boot-Stater来实现特定功能。
引入配置
开始之前创建maven项目,导入创建SpringStater需要配置:
<?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.2.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.xy</groupId>
<artifactId>simple-spring-boot-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>simple-spring-boot-starter</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<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-autoconfigure</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/
*.xml</include>
</includes>
</resource>
</resources>
</build>
</project>
spring-boot-configuration-processor 引入这个包主要为了生成metadata.json,方便在yml文件中引入配置时提供代码提示。
Spring官方对starter的命名有一定的规范,例如spring 官方定义的包命名为:spring-boot-starter-{name},如果是非官方版本的stater定义为:{name}-spring-boot-starter。
实现步骤
1.在simple-spring-boot-starter项目中定义需要实现的功能模块,定义简单的主体方法,helloWorld(String word)实现字符串的拼接。
public class ExampleService {
private String prefix;
private String suffix;
public ExampleService(String prefix, String suffix){
this.prefix = prefix;
this.suffix = suffix;
}
public String helloWorld(String word){
return prefix + suffix + word;
}
}
2.在SpringBoot中通过<font color=’‘#ff3333’’>@ConfigurationProperties</font>注解通过前缀+后缀批注去除yml中配置文件内容。
@ConfigurationProperties("example.service")
public class ExampleServiceProperties {
private String prefix;
private String suffix;
public String getPrefix() {
return prefix;
}
public String getSuffix() {
return suffix;
}
public void setSuffix(String suffix) {
this.suffix = suffix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
}
3.最重要的是定义AutoConfiguration,在simple-spring-boot-stater项目中定义ExampleAutoConfigure 实现自动注入。
- @Configuration 配置类注解
- @ConditionalOnClass(ExampleService.class) : 当在classpath下 有ExampleService 这个类时才进行加载。
- @EnableConfigurationProperties(ExampleServiceProperties.class) // 开启允许ExampleServiceProperties获取yml配置
@Configuration
@ConditionalOnClass(ExampleService.class)
@EnableConfigurationProperties(ExampleServiceProperties.class)
public class ExampleAutoConfigure {
private final ExampleServiceProperties properties;
@Autowired
public ExampleAutoConfigure(ExampleServiceProperties serviceProperties){
this.properties = serviceProperties;
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "example.service", value = "enabled", havingValue = "true")
ExampleService exampleService(){
return new ExampleService(properties.getPrefix(), properties.getSuffix());
}
}
在定义bean方法会使用到一些相关注解
-
@ConditionalOnMissingBean
: 表示Spring context 中不存在该bean
-
@ConditionalOnProperty(prefix = "example.service", value = "enabled", havingValue = "true")
: example.service.enabled : true, 这种情况才会加载这个Bean
springBoot 中相关注解: @Conditional 相关注解
条件化注解 | 配置生效条件 | 备注 |
---|---|---|
@ConditionalOnBean | 配置了某个特定的Bean | |
@ConditionalOnMissingBean | Spring Context中没有配置特定的Bean | |
@ConditionalOnClass | classPath下有指定的类 | |
@ConditionalOnMissingClass | classPath下没有指定的类 | |
@ConditionalOnExpression | 在给定的Spring Expression Language 表达式计算结果为true | |
@ConditionalOnJava | java的版本匹配特定指或者一个范围值 | |
@ConditionalOnProperty | 制定配置属性要有一个明确的值 | |
@ConditionalOnResource | classPath下有指定的资源 | |
@ConditionalOnWebApplication | 指定是一个web应用程序 | |
@ConditionalOnNotWebApplication | 指定不是一个web应用程序 |
4.在resouces 环境下创建META-INF目录,然后在创建spring.factories文件:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.xy.stater.config.ExampleAutoConfigure
spring Boot 项目启动时会到这个目录下spring.factories文件中查找org.springframework.boot.autoconfigure.EnableAutoConfiguration这个配置下的文件,装载到spring容器中。
测试
1.新建项目依赖这个项目进行测试
引入maven项目
<dependency>
<groupId>com.xy</groupId>
<artifactId>simple-spring-boot-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
2.在application.properties 中添加配置
example.service.prefix=nihao
example.service.suffix=world
example.service.enabled=true
3.在spring测试类中调用ExampleService中的方法
@RunWith(SpringRunner.class)
@SpringBootTest
public class SimpleStaterTest {
@Resource
private ExampleService exampleService;
@Test
public void test(){
String how = exampleService.helloWorld("how");
System.out.println(how);
}
}
4.方法执行结果
nihaoworldhow