现如今的Java后端开发范畴之内,Spring Boot已然演变成一项必须具备的核心技能,它的问世完全改变了传统的Java企业级应用开发方式,其核心吸引力在于自带了一套强劲的自动化配置机制。这套机制,对“开箱即用”理念作出了堪称完美的诠释,它准许开发者,凭借简单的依赖引入方式,能够迅即搭建起达到生产级别的应用程序,进而把精力集中于业务逻辑的达成之上。
深入理解Spring Boot的自动化配置原理
然而,Spring Boot具备的所谓聪明的地方在于,在项目开始启动这个时刻,它会去搜寻所有依赖Jar包路径之中的那个名为META-INF/spring.factories的文件。
这样一个进程近似于Java原本的、名为SPI(Service Provider Interface)的技术机制。Spring Boot会去读取于该文件里所配置的、名为自动配置类的内容,之后凭借当前项目的类路径之下是不是存在特定的类(也就是是否引入了相对应的依赖),以此来判定是否去加载这些配置。于微观层面,借由@Conditional系列注解,像@ConditionalOnClass、@ConditionalOnBean这般,达成了更为精准的条件化配置加载。这种设计,实际上是由“基于接口的编程+策略模式+配置文件”这种组合来实现的动态加载机制,此机制的存在,确保了是只有在特定条件被满足的时候,相应的Bean才会被注册到IOC容器当中去。
实战演练:如何自定义一个Spring Boot Starter

在对原理有所领会之后,着手去达成一个自行定义的 Starter,这般行径乃是对知识予以巩固的最为理想的途径。自行定义 Starter,其重点聚焦于满足两项条件:其一,它要能够以自动的方式将项目所需要的依赖环境配置构建起来 ;其二,它要可以依据项目的具体信息,以自动的形式生成并且把 Bean 注册到容器当中。接下来借助一个具体的实例去对实现的过程进行剖析。
第一步:创建自定义Starter工程并添加依赖
打造一个具备基础性质的 Maven 项目,于 pom.xml 里引入诸如 spring-boot-autoconfigure 这般必要的依赖,此乃我们达成自动化配置的根基所在。
org.springframework.boot
spring-boot-autoconfigure
第二步:编写配置属性类与业务服务类
定义这样一种类,它被称作配置属性类,其作用是用来映射存在于application.properties里的配置项。借助@ConfigurationProperties注解去指定配置前缀,像my.custom这样的形式。
@ConfigurationProperties(prefix = "my.custom")
public class CustomProperties {
private String message = "ok"; // 默认值
// getters and setters
}
org.springframework.boot
spring-boot-autoconfigure
2.0.0.RELEASE
org.springframework.boot
spring-boot-configuration-processor
2.0.0.RELEASE
true

与此同时,去创建一个服务类,此服务类里面含有我们Starter所要提供的核心业务逻辑,而该服务类将会依赖配置属性类。
public class CustomService {
private String message;
public CustomService(String message) { this.message = message; }
public String sayHello() { return message; }
}
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "spring.tian")
public class TianProperties {
private String name;
private int age;
private String sex = "M";
//省略 get set 方法
}
第三步:创建自动配置类与注册文件
public class TianService {
private TianProperties properties;
public TianService() {
}
public TianService(TianProperties userProperties) {
this.properties = userProperties;
}
public void sayHello(){
System.out.println("hi, 我叫: " + properties.getName() +
", 今年" + properties.getAge() + "岁"
+ ", 性别: " + properties.getSex());
}
}

本质要点是搭建自动配置类,借助@Configuration以及@ConditionalOnXxx注解去界定Bean的生成条件。一旦探测到类路径之中存在CustomService类,才会去构建这个Bean。
@Configuration
@EnableConfigurationProperties(TianProperties.class)
@ConditionalOnClass(TianService.class)
@ConditionalOnProperty(prefix = "spring.tian", value = "enabled", matchIfMissing = true)
public class TianServiceAutoConfiguration {
@Autowired
private TianProperties properties;
@Bean
@ConditionalOnMissingBean(TianService.class)
public TianService tianService() {
return new TianService(properties);
}
}
@Configuration
@ConditionalOnClass(CustomService.class)
@EnableConfigurationProperties(CustomProperties.class)
public class CustomAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public CustomService customService(CustomProperties properties) {
return new CustomService(properties.getMessage());
}
}
于resources目录以内,去创建META-INF文件夹,而且要在该文件夹当中,去新建一个spring.factories文件,随后把自动配置类的详细限定名给写进去,以此方便Spring Boot启动之际可以实现加载。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.tian.TianServiceAutoConfiguration
org.springframework.boot.autoconfigure.EnableAutoConfiguration=
com.example.custom.CustomAutoConfiguration
做完上述那些步骤之后,把那个项目进行打包,使之成为一个Jar文件,如此一来,一个自定义的Starter便诞生了。
在项目中使用并验证自定义Starter
去创建一个全新型的Spring Boot项目,随后要在其的pom.xml里面引入我们刚刚进行打包好的自定义Starter依赖。之后呢,在application.properties里边,我们能够借用通过的my.custom.message属性来把默认的配置值给覆盖掉。
编写一个简单的Controller来验证效果:
com.tian
spring-boot-tian-starter
1.0-SNAPSHOT
@RestController
public class TestController {
@Autowired
private CustomService customService;
@GetMapping("/my/hello")
public String hello() {
return customService.sayHello();
}
}
@SpringBootApplication
@EnableEurekaServer
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
开启项目,前往localhost:9091/my/hello进行访问,浏览器顺利返回"ok"(或者是自定义的讯息),并且控制台不存在任何异常状况,这表明我们自行定义的自动化配置已然成功发挥效用,Bean被准确无误地注入到了IOC容器里。截至此刻,我们达成了一个自定义Starter的完整实现,深切领略到了Spring Boot“减少大量的配置项”以及“约定大于配置”的核心优势。一旦掌握这一方向,深入洞悉Spring Boot的奥秘就不再遥远。
spring.tian.name=tian
spring.tian.age=22
spring.tian.sex=M

Comments NOTHING