SpringBoot针对日常企业应用场景提供了各种spring-boot-starter依赖模块,所有这些依赖模块都遵循着约定俗成的默认配置,并允许我们调整这些配置,即遵循“约定大于配置”的理念。SpringBoot通过AutoConfiguration模块自动装配官方(以spring-boot-starter-xxx方式命名)、第三方以及自定义(以xxx-spring-boot-starter方式命名)的starter.
当我们向其他项目提供jar包时,可自定义为starter,SpringBoot项目即可像自动加载spring-boot-starter-jdbc、spring-boot-starter-web等一样自动加载您的starter,下面即为一个最简单的自定义starter例子和原理介绍:
1. Pom依赖
4.0.0
com.zhangwei
demo-spring-boot-starter
1.0-SNAPSHOT
org.springframework.boot
spring-boot-starter-parent
2.0.0.RELEASE
1.8
org.springframework.boot
spring-boot-configuration-processor
true
org.springframework.boot
spring-boot-autoconfigure
org.projectlombok
lombok
1.18.8
其中spring-boot-starter-parent是springboot starter的父级依赖,统一封装了自定义starter所需的依赖和插件;
spring-boot-configuration-processor是springboot提供的工具包,用于编译期给标注了@ConfigurationProperties的配置类生成元数据信息,当在properties文件中配置相关属性时,就会根据元数据给出相应提示;
spring-boot-autoconfigure是springboot的自动装配模块,这里主要提供了自定义starter所需的注解,springboot会根据这些标记的注解完成自动装配逻辑;
lombok:非必须,其作用是帮助在编译时自动为属性生成getter/setter方法,减少代码量。
2. 定义一个配置信息实体类
package com.zhangwei;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "demo")
@Data
public class DemoProperties {
private String name = "zhangwei";
private String city = "beijing";
}
其中@ConfigurationProperties可以把相同前缀的配置信息映射到实体类中的属性。
3. 定义一个Service
package com.zhangwei;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Service;
@EnableConfigurationProperties(DemoProperties.class)
public class DemoService {
@Autowired
private DemoProperties demoProperties;
public String say() {
return "name:" + demoProperties.getName() + ",city:" + demoProperties.getCity();
}
}
其中@EnableConfigurationProperties(xxx.class),用于开启属性配置类,并将该类加入spring容器,但是前提条件是spring能够发现DemoService类。
4. 重点:配置META-INF/spring.factories文件
在resources目录下新建META-INF/spring.factories文件,并配置:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.zhangwei.DemoService
springboot在启动时,借助@EnableAutoConfiguration中@Import的帮助,将所有符合自动配置条件的bean定义加载到IoC容器,即会从classpath中搜索所有META-INF/spring.factories配置文件,并将其中org.spring-framework.boot.autoconfigure.EnableAutoConfiguration对应的配置项通过反射(Java Reflection)实例化为对应的JavaConfig形式的IoC容器配置类,然后汇总为一个并加载到IoC容器。自动配置的幕后英雄SpringFactoiesLoader是属于Spring框架私有的一种扩展方案(类似于Java的SPI方案java.util.ServiceLoader),其主要功能就是从指定的配置文件META-INF/spring.factories加载配置。
SPI,全称Service Provider Interface,是一种服务发现机制。它通过在ClassPath路径下的META-INF/services文件夹查找文件,自动加载文件里所定义的类。这一机制为很多框架扩展提供了可能,比如在Dubbo、JDBC中都使用到了SPI机制。
5. 测试验证
将自定义的demo-spring-boot-starter通过maven命令mvn clean install -U打成jar包,并安装在本地,在另一web项目中引入该jar包,依赖坐标如下:
com.zhangwei
demo-spring-boot-starter
1.0-SNAPSHOT
编写测试用的controller如下:
@Controller
@RequestMapping("/")
public class IndexController {
@Autowired
private DemoService demoService;
@RequestMapping("/")
@ResponseBody
public Result index() {
return new Result(200, demoService.say());
}
}
配置文件如下:
demo.name=lisi
demo.city=wuhan
访问controller,如下: