spring boot的自动配置功能拯救了无数程序员于配置地狱,我们通常通过spring-boot-starter的方式导入依赖,就可以便捷地使用其自动为我们注入的对象,那么spring-boot-starter是怎么实现的呢?
1、starter项目结构
需要我们实现的主要有是处:
- AutoConfiguration类:将bean注入spring容器的自动配置类
- properties(可选):提供yml、properties文件中的配置选项
- service:要注入的对象的具体实现
- spring.factories:提供信息以告知spring-boot自动配置类的路径
所使用的maven依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>2.2.12.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.2.12.RELEASE</version>
</dependency>
</dependencies>
2、具体实现
先上图:
2.1、读取properties
先上代码:
@ConfigurationProperties(prefix = "kloein.hello")
public class GreetProperties {
private String name;
private String message;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
@ConfigurationProperties:spring提供的读取配置文件的注解,prefix即配置名的的前缀。
对于GreetProperties文件中的name和message字段,有了该注解便可以这样从yml中读取:
kloein:
hello:
name: kloein
message: good morning
2.2、service实现
出于演示目的,仅仅定义简单的服务。
接口:
public interface GreetService {
String greet();
}
实现
@Service
public class GreetServiceImpl implements GreetService {
@Autowired
private GreetProperties greetProperties;
@Override
public String greet() {
return greetProperties.getName()+":"+greetProperties.getMessage();
}
}
2.3、AutoConfiguration类的实现
事实上,AutoConfiguration依旧是基于 @Configuration实现的。
回顾我们spring boot对于自动配置的:只要导入starter,如果没有自己定义所需的bean,就会帮我们配置。因此我们需要 @ConditionalOnMissingBean()注解:没有bean才注入
此外,针对我们2.1读取配置的功能,也需要注解 @EnableConfigurationProperties()
代码如下:
@Configuration
@ConditionalOnMissingBean(GreetService.class)
@EnableConfigurationProperties(GreetProperties.class)
public class GreetServiceAutoConfiguration {
@Bean
public GreetService greetService() {
GreetServiceImpl greetService = new GreetServiceImpl();
return greetService;
}
}
2.4、spring.factories
最后,我们还需要告知spring我们要读取上方的配置类,spring容器启动时,会读取 /resources/META-INF/spring.factories文件,因此我们需要在其中指定我们配置类的位置。下列配置文件的意义是当开启 @EnableAutoConfiguration注解时会自动扫描com.example.autoconfig. GreetServiceAutoConfiguration文件
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.autoconfig.GreetServiceAutoConfiguration
3.测试
3.1、将jar包装入本地maven仓库
clean->install
3.3、配置yml
在application.yml中配置2.1中的properties信息
server:
port: 8011
kloein:
hello:
name: kloein
message: good morning
3.4、简单的controller
@RestController
public class GreetController {
@Autowired
private GreetService greetService;
@RequestMapping("/greet")
public String greet() {
String greet = greetService.greet();
return greet;
}
}