SpringBoot学习系列(十二)------自定义starters
前言
SpringBoot的使用方便了我们的开发,究其原因,还是因为我们使用了很多的的starters,在我们导入这些starters的依赖以后,SpringBoot会帮我们注入很多的自动配置,在这里,我们可以来研究一下starters,实现自己的starters.
正文
1. WebMvcAutoConfiguration
我们查看这个类,可以发现有几个需要注意的注解:
@Configuration //指定这个类是一个配置类
@ConditionalOnWebApplication //所有已ConditionalOnXXX开头的,都是在满足该条件的情况下,配置才生效
@AutoConfigureAfter //指定自动配置类的顺序
@Bean //给容器中添加组件
@ConfigurationProperties //根据相关的Properties属性类来绑定相关的配置
@EnableConfigurationProperties //让Properties生效,并加入容器中
//要想在启动的时候自动配置类能被加载,还必须要将配置类放在META/INF/spring.factories中指定
//如下指定:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
2. SpringBoot默认的starters的模式
- 启动器用来做依赖导入
- 额外写一个自动配置的模块
- 启动器依赖自动配置模块,在使用的时候只需要引入启动器(starter)即可
3. 实现自定义启动器
- 创建一个空的工程模块,工程名为:
spring-boot-starter
- 在该工程下创建2个模块,一个作为启动器,一个作为自动配置模块:
- 我们在starter中引入starter-autoconfigurer:
<!--引入自动配置模块-->
<dependencies>
<dependency>
<groupId>com.xiaojian.starter</groupId>
<artifactId>xiaojian-spring-boot-starter-autoconfigurer</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
- 创建一个绑定配置文件属性的配置类,用
@ConfigurationProperties
来标注:
package com.xiaojian.starter;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* ConfigurationProperties注解表示将配置文件中前缀为xiaojian.hello的属性绑定到该类的属性中
*/
@ConfigurationProperties(prefix = "xiaojian.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;
}
}
- 接着我们定义一个service作为自动配置后主动执行的组件,在这个service中我们可以加入上一步中定义的HelloProperties,要注意,要想这个helloProperties被别的模块使用,需要加入get/set方法:
package com.xiaojian.starter;
public class HelloService {
HelloProperties helloProperties;
public HelloProperties getHelloProperties() {
return helloProperties;
}
public void setHelloProperties(HelloProperties helloProperties) {
this.helloProperties = helloProperties;
}
public String sayHello(String name) {
return helloProperties.getPrefix() + "-"
+ name + "-" + helloProperties.getSuffix();
}
}
//这样,我们在调用sayHello方法的时候,会根绝配置文件中配置的前缀和后缀2个属性,加上我们传入的name,返回给调用者
- 编写自动配置类:
package com.xiaojian.starter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* helloservice组件的自动配置类
*/
@Configuration //指定这是一个配置类
@ConditionalOnWebApplication //指定只有是web应用时,改配置才生效
@EnableConfigurationProperties(HelloProperties.class) //激活和属性文件绑定的类
public class HelloServiceAutoConfiguration {
@Autowired
HelloProperties helloProperties;
@Bean
public HelloService helloService() {
HelloService helloService = new HelloService();
//在这里要把配置文件中的properties类设置到service中
helloService.setHelloProperties(helloProperties);
return helloService;
}
}
- 要在classpath下创建一个META-INF文件夹,并在该文件夹下创建文件
spring.factories
,在文件中指定自定义自动配置类的全路径:
至此,我们自定义的starter全部完成,我们一起来看一下我们做了什么:
- 我们编写了一个自动配置类
HelloServiceAutoConfiguration
,注解@Configuration
指定了它是一个配置类,注解@ConditionalOnWebApplication
限定它只有在web环境中生效,注解@EnableConfigurationProperties(HelloProperties.class)
标注它在启用时,会激活属性类HelloProperties
,并且绑定到自身. - 在
HelloServiceAutoConfiguration
中我们注入了一个bean,并将配置文件中以xiaojian.hello
开头的属性类设置到helloservice中. - 在
spring.factories
中,我们将HelloServiceAutoConfiguration
配置进去,这样在启动的时候,我们自定义的自动配置类就能加载了.
4. 测试自定的starter
在前面我们自定义好了自己的starter,现在我们可以来创建一个工程测试一下:
我们创建好工程以后,在pom.xml文件中引入我们自定义的模块:
<!--引入自定义的starter-->
<dependency>
<groupId>com.xiaojian</groupId>
<artifactId>xiaojian-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
在工程中编写一个测试的controller:
@RestController
public class HelloController {
@Autowired
private HelloService helloService;
@GetMapping("/hello")
public String hello(){
return helloService.sayHello("张三");
}
}
在该工程的配置文件中定义前缀和后缀:
xiaojian.hello.prefix=亲爱的
xiaojian.hello.suffix=你好
现在我们访问http://localhost:8080/hello
来测试:
可以看到我们自定义的配置起作用了.
总结
自定义自动配置模块,能帮助我们理解SpringBoot的starter实现过程,在技术的学习上,我们不仅要会用,也要对每一门技术的由来和原理有一定的认识.