Starters可以理解为启动器,它包含了一系列可以集成到应用里面的依赖包,你可以一站式集成Spring及其他技术,而不需要到处找示例代码和依赖包。如你想使用Spring JPA访问数据库,只要加入spring-boot-starter-data-jpa启动器依赖就能使用了。
Starters包含了许多项目中需要用到的依赖,它们能快速持续的运行,都是一系列得到支持的管理传递性依赖。
在没有starter之前,假如我想要在Spring中使用jpa,那我可能需要做以下操作:
像上面这样的操作也不算不行,事实上我们在没有starter之前都是这么干的,但是这样做有几个问题:
starter的理念:starter会把所有用到的依赖都给包含进来,避免了开发者自己去引入依赖所带来的麻烦。需要注意的是不同的starter是为了解决不同的依赖,所以它们内部的实现可能会有很大的差异,例如jpa的starter和Redis的starter可能实现就不一样,这是因为starter的本质在于synthesize,这是一层在逻辑层面的抽象,也许这种理念有点类似于Docker,因为它们都是在做一个“包装”的操作,如果你知道Docker是为了解决什么问题的,也许你可以用Docker和starter做一个类比。
starter的实现:虽然不同的starter实现起来各有差异,但是他们基本上都会使用到两个相同的内容:ConfigurationProperties和AutoConfiguration。因为Spring Boot坚信“约定大于配置”这一理念,所以我们使用ConfigurationProperties来保存我们的配置,并且这些配置都可以有一个默认值,即在我们没有主动覆写原始配置的情况下,默认值就会生效,这在很多情况下是非常有用的。除此之外,starter的ConfigurationProperties还使得所有的配置属性被聚集到一个文件中(一般在resources目录下的application.properties),这样我们就告别了Spring项目中XML地狱。
Spring Boot官方的启动器都是以spring-boot-starter-命名的,代表了一个特定的应用类型。
第三方的启动器不能以spring-boot开头命名,它们都被Spring Boot官方保留。一般一个第三方的应该这样命名,像mybatis的mybatis-spring-boot-starter。
启动器名称 | 功能描述 |
---|---|
spring-boot-starter | 包含自动配置、日志、YAML的支持。 |
spring-boot-starter-web | 使用Spring MVC构建web 工程,包含restful,默认使用Tomcat容器。 |
… | … |
启动器名称 | 功能描述 |
---|---|
spring-boot-starter-actuator | 提供生产环境特性,能监控管理应用。 |
启动器名称 | 功能描述 |
---|---|
spring-boot-starter-json | 提供对JSON的读写支持。 |
spring-boot-starter-logging | 默认的日志启动器,默认使用Logback。 |
… | … |
创建自己的Spring Boot Starter
如果你想要自己创建一个starter,那么基本上包含以下几步
首先新建一个Maven项目,设置 pom.xml 文件如下:
4.0.0
http-starter
0.0.1-SNAPSHOT
org.springframework.boot
spring-boot-starters
1.5.2.RELEASE
org.springframework.boot
spring-boot-starter
org.projectlombok
lombok
1.16.10
创建proterties类来保存配置信息:
@ConfigurationProperties(prefix = “http”) // 自动获取配置文件中前缀为http的属性,把值传入对象参数
@Setter
@Getter
public class HttpProperties {
// 如果配置文件中配置了http.url属性,则该默认属性会被覆盖
private String url = "http://www.baidu.com/";
}
上面这个类就是定义了一个属性,其默认值是 http://www.baidu.com/,我们可以通过在 application.properties 中添加配置 http.url=https://www.zhihu.com 来覆盖参数的值。
创建业务类:
@Setter
@Getter
public class HttpClient {
private String url;
// 根据url获取网页数据
public String getHtml() {
try {
URL url = new URL(this.url);
URLConnection urlConnection = url.openConnection();
BufferedReader br = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "utf-8"));
String line = null;
StringBuilder sb = new StringBuilder();
while ((line = br.readLine()) != null) {
sb.append(line).append("\n");
}
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
return "error";
}
}
这个业务类的操作非常简单,只包含了一个 url 属性和一个 getHtml 方法,用于获取一个网页的HTML数据,读者看看就懂了。
创建AutoConfiguration
@Configuration
@EnableConfigurationProperties(HttpProperties.class)
public class HttpAutoConfiguration {
@Resource
private HttpProperties properties; // 使用配置
// 在Spring上下文中创建一个对象
@Bean
@ConditionalOnMissingBean
public HttpClient init() {
HttpClient client = new HttpClient();
String url = properties.getUrl();
client.setUrl(url);
return client;
}
}
在上面的AutoConfiguration中我们实现了自己要求:在Spring的上下文中创建了一个HttpClient类的bean,并且我们把properties中的一个参数赋给了该bean。
关于@ConditionalOnMissingBean 这个注解,它的意思是在该bean不存在的情况下此方法才会执行,这个相当于开关的角色,更多关于开关系列的注解可以参考这里。
最后,我们在 resources 文件夹下新建目录 META-INF,在目录中新建 spring.factories 文件,并且在 spring.factories 中配置AutoConfiguration:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.nosuchfield.httpstarter.HttpAutoConfiguration
到此,我们的starter已经创建完毕了,使用Maven打包该项目。之后创建一个SpringBoot项目,在项目中添加我们之前打包的starter作为依赖,然后使用SringBoot来运行我们的starter,代码如下:
@Component
public class RunIt {
@Resource
private HttpClient httpClient;
public void hello() {
System.out.println(httpClient.getHtml());
}
}
正常情况下此方法的执行会打印出url http://www.baidu.com/
的HTML内容,之后我们在application.properties中加入配置:
http.url=https://www.zhihu.com/
再次运行程序,此时打印的结果应该是知乎首页的HTML了,证明properties中的数据确实被覆盖了。
参考:
https://mp.weixin.qq.com/s/9HJVGlplze5p0eBayvhFCA (Spring Boot Starters启动器)
https://blog.csdn.net/weixin_34162695/article/details/92081815?utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control (深入理解 Spring Boot Starters 原理)