为什么要自定义starter ?
SpringBoot优点之一简化编码,在使用Spring创建项目时,需要在pom文件中添加多个依赖,而SpringBoot则会 帮助开发者快速启动一个web容器,只需要在pom中添加一个starter依赖即可,大大简化了编码,不用一个个导入依赖。
所以在开发项目时有时为了方便拓展可以自定义写自己的starter,方便自己的项目特定场景需求。
原理:
首先,SpringBoot在启动时会去依赖的starter包中寻找resource/META-IFN/spring.factories文件,然后根据文件中配置的jar包去扫描项目所依赖的jar包;
然后,根据spring.factories配置加载AutoConfigure类;
最后,根据@Conditional注解的条件,进行自动配置并将Bean注入Spring Context上下文当中;
实现步骤:
步骤一:创建一个SpringBoot项目,在pom.xml中添加如下依赖
<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>
其中spring-boot-configuration-processor的作用是编译时生成spring-configuration-metadata.json,此文件主要给IDE使用。
当配置此jar相关配置属性在application.porperties,可以用ctrl + 鼠标左键点击属性名,IDE会跳转到你配置此属性的类中。
步骤二:artifactId 命名应遵循{name}-spring-boot-starter 的格式,比如:
<groupId>com.lk</groupId>
<artifactId>simple-spring-boot-starter</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
步骤三:编写Service类
本次Starter示例主要实现的功能:提供一个Service,包含一个能够将配置文件中配置的字符串可以根据传入的字符进行分割的方法String[] split(String separatorChar)。
public class StarterService {
private String config;
public StarterService(String config) {
this.config = config;
}
public String[] split(String separatorChar) {
return StringUtils.split(this.config, separatorChar);
}
}
步骤四:编写配置文件读取类
@ConfigurationProperties("example.service")
public class StarterServiceProperties {
private String config;
public void setConfig(String config) {
this.config = config;
}
public String getConfig() {
return config;
}
}
步骤五:编写AutoConfigure类
@Configuration
@ConditionalOnClass(StarterService.class)
@EnableConfigurationProperties(StarterServiceProperties.class)
public class StarterAutoConfigure {
@Autowired
private StarterServiceProperties properties;
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "example.service", value = "enabled", havingValue = "true")
StarterService starterService (){
return new StarterService(properties.getConfig());
}
}
重要注解:
- @ConditionalOnClass :当classpath下发现该类的情况下进行自动配置;
- @ConditionalOnMissingBean:当Spring Context中不存在该Bean时创建;
@ConditionalOnProperty(prefix="example.service", value="enabled", havingValue="true"):当配置文件中example.service.enabled=true时;
步骤六:在resource/META-INF/下创建spring.factories文件,并添加如下内容:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.lk.service.StarterAutoConfigure
整体项目目录结构,如图
至此,我们整个Starter代码部分全部完成,下面就是将项目执行mvn install 打包并安装到本地Maven仓库中。
安装指定文件到本地仓库命令:mvn install:install-file
-DgroupId=<groupId> : 设置上传到仓库的包名
-DartifactId=<artifactId> : 设置该包所属的模块名
-Dversion=1.0.0 : 设置该包的版本号
-Dpackaging=jar : 设置该包的类型(很显然jar包)
-Dfile=<myfile.jar> : 设置该jar包文件所在的路径与文件名
========================测试================================
1、将Starter项目依赖添加到我们另一SpringBoot项目中:
<dependency>
<groupId>com.lk</groupId>
<artifactId>simple-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
2、在application.properties 添加如下内容:
#IP地址列表
example.service.enabled=true
example.service.config=192.168.3.22,10.192.16.1
3、本地进行Junit单元测试:
@Autowired
private StarterService starterService;
@Test
void testStarterService() {
try {
String[] ips = starterService.split(",");
for (String ip: ips) {
System.out.println("打印IP:" + ip);
}
} catch (Exception e) {
e.printStackTrace();
}
}