spring-boot-starter的核心就是依赖管理、约定配置、自动装配。
依赖管理:starter模块会将它所需要的依赖自动引入,项目无需再引入。
约定配置:starter会定义它所需要的配置项,同时会给这些配置项默认值。如果你使用默认配置,则项目无需再配置;如果你使用默认配置,则项目属性文件添加自己的配置项即可。
自动装配:starter模块中的AutoConfiguration会自动根据定义的配置项做一些初始化的工作,如初始化Bean到spring容器。
在实际应用中,我们可以自定义 starter 来实现项目中复用度高的业务,让别的模块能很方便的引入使用。
下面我们来编写一个简单的stater。参照mybatis的starter结构,starter由两个部分构成:starter和autoconfigure。starter里面没有内容,但pom里面引入了autoconfigure,主要是一个依赖传递,起了依赖保护的作用;autoconfigure里面才是真正实现功能的地方。
参照此结构,我们建一个hello的starter,包含两个工程:hello-spring-boot-autoconfigure和hello-spring-boot-starter。

一、hello-spring-boot-autoconfigure
创建hello-spring-boot-autoconfigure工程,pom.xml引入自动装配需要的依赖:
<?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>
<groupId>com.jancen</groupId>
<artifactId>hello-spring-boot-autoconfigure</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>hello-spring-boot-autoconfigure</name>
<description>这是一个自定义的springboot的starter</description>
<properties>
<java.version>1.8</java.version>
<boot.version>2.2.5.RELEASE</boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>${boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>${boot.version}</version>
</dependency>
</dependencies>
</project>
编写属性配置类,将配置文件中的属性绑定到该类中的属性
@ConfigurationProperties(prefix = "spring.hello")
public class HelloProperties {
private String name = "Jancen";
private int age = 10;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
编写业务类实现功能,在使用时供项目调用
public class HelloService {
private HelloProperties properties;
public void setProperties(HelloProperties properties) {
this.properties = properties;
}
public String hello(){
Random random = new Random();
return properties.getName() + ",你的编号是" + random.nextInt(properties.getAge());
}
}
自动装配类,使配置生效,并且把服务注入到容器中
@Configuration
@EnableConfigurationProperties(HelloProperties.class)//使配置文件生效
@ConditionalOnClass(HelloService.class)//classpath存在指定类时自动装配
@ConditionalOnProperty(prefix = "spring.hello", value = "enabled", matchIfMissing = true)//当配置文件中example.service.enabled=true时进行自动配置,默认为true。
public class HelloAutoConfiguration {
@Autowired
private HelloProperties properties;
//注入bean实例
@Bean
@ConditionalOnMissingBean(HelloService.class)//当Spring Context中有指定的Bean的条件下
public HelloService helloService(){
HelloService service = new HelloService();
service.setProperties(properties);
return service;
}
}
在 src/main/resource/META-INF目录下创建一个配置文件 spring.factories,指定自动装配的类,这个是重点。spring-core中的SpringFactoriesLoader通过检索这个文件中的内容,获取到指定的配置类。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.jancen.starter.configure.HelloAutoConfiguration
以上starter就创建完成了,使用maven install打成jar包。
二、hello-spring-boot-starter
创建hello-spring-boot-starter工程,pom引入hello-spring-boot-autoconfigure依赖。
<?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>
<groupId>com.jancen</groupId>
<artifactId>hello-spring-boot-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>hello-spring-boot-starter</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.jancen</groupId>
<artifactId>hello-spring-boot-autoconfigure</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
好了,starter项目创建好了。其他什么多余的代码都不要,统统删掉。
使用maven install将starter达成jar包。
三、测试使用starter
创建测试工程,在pom里面映入我们自己的starter的依赖,使用starter里面初始化的HelloService这个Bean。
<dependency>
<groupId>com.jancen</groupId>
<artifactId>hello-spring-boot-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
编写测试类,测试HelloService
@SpringBootTest
class HelloStarterTestApplicationTests {
@Autowired
private HelloService helloService;
@Test
void testHello() {
System.out.println(helloService.hello());
}
}
当我们application.properties文件里面什么配置都没有的时候,name和age配置项使用的是默认值,打印出来的日志如下:
2020-03-13 15:30:13.219 INFO 5944 --- [ main] c.j.t.HelloStarterTestApplicationTests :
Jancen,你的编号是7
当我们在application.properties自定义配置项的值时:
spring.hello.name=Hanmeimei
spring.hello.age=20
spring.hello.enabled=true
打印日志:
2020-03-13 15:36:26.030 INFO 10996 --- [ main] c.j.t.HelloStarterTestApplicationTests :
Hanmeimei,你的编号是9
说明项目成功调用starter中自定义的业务方法,并获取到了绑定的属性值。
四、最后
starter的自动装配特性在实际项目中非常有用。例如,项目要集成cache缓存框架,但是缓存框架有很多,不同项目可能使用不同的缓存框架。可以通过自己编写starter来自动识别集成哪个缓存框架,类似于jdbcTemplate。
网友评论