现如今的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

编程入门SpringBoot入门_自动配置依赖管理_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
  

编程入门SpringBoot入门_自动配置依赖管理_Spring Boot starter机制

与此同时,去创建一个服务类,此服务类里面含有我们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());
    }
}

自动配置依赖管理_Spring Boot starter机制_编程入门SpringBoot入门

本质要点是搭建自动配置类,借助@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