Spring Boot Starters是什么?
版权声明:该文转自: http://www.nosuchfield.com/2017/10/15/Spring-Boot-Starters/。版权归原创作者,在此对原作者的付出表示感谢!
starter是SpringBoot中的一个新发明,它有效的降低了项目开发过程的复杂程度,对于简化开发操作有着非常好的效果。本文转载了一片文章,详细介绍了spring boot stater是什么?它的作用是什么?
Spring Boot Starter是在SpringBoot组件中被提出来的一种概念,stackoverflow上面已经有人概括了这个starter是什么东西,想看完整的回答戳这里(https://stackoverflow.com/questions/28273543/what-are-spring-boot-starter-jars/28273660#28273660)
大概意思就是说starter是一种对依赖的synthesize(合成),这是什么意思呢?我可以举个例子来说明。
传统的做法
在没有starter之前,假如我想要在Spring中使用jpa,那我可能需要做以下操作:
- 在Maven中引入使用的数据库的依赖(即JDBC的jar)
- 引入jpa的依赖
- 在xxx.xml中配置一些属性信息
- 反复的调试直到可以正常运行
需要注意的是,这里操作在我们每次新建一个需要用到jpa的项目的时候都需要重复的做一次。也许你在第一次自己建立项目的时候是在Google上自己搜索了一番,花了半天时间解决掉了各种奇怪的问题之后,jpa终于能正常运行了。有些有经验的人会在OneNote上面把这次建立项目的过程给记录下来,包括操作的步骤以及需要用到的配置文件的内容,在下一次再创建jpa项目的时候,就不需要再次去Google了,只需要照着笔记来,之后再把所有的配置文件copy&paste就可以了。
像上面这样的操作也不算不行,事实上我们在没有starter之前都是这么干的,但是这样做有几个问题:
- 如果过程比较繁琐,这样一步步操作会增加出错的可能性
- 不停地copy&paste不符合Don’t repeat yourself精神
- 在第一次配置的时候(尤其如果开发者比较小白),需要花费掉大量的时间
使用Spring Boot Starter提升效率
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地狱。
starter的整体逻辑:
上面的starter依赖的jar和我们自己手动配置的时候依赖的jar并没有什么不同,所以我们可以认为starter其实是把这一些繁琐的配置操作交给了自己,而把简单交给了用户。除了帮助用户去除了繁琐的构建操作,在“约定大于配置”的理念下,ConfigurationProperties还帮助用户减少了无谓的配置操作。并且因为 application.properties
文件的存在,即使需要自定义配置,所有的配置也只需要在一个文件中进行,使用起来非常方便。
了解了starter其实就是帮助用户简化了配置的操作之后,要理解starter和被配置了starter的组件之间并不是竞争关系,而是辅助关系,即我们可以给一个组件创建一个starter来让最终用户在使用这个组件的时候更加的简单方便。基于这种理念,我们可以给任意一个现有的组件创建一个starter来让别人在使用这个组件的时候更加的简单方便,事实上Spring Boot团队已经帮助现有大部分的流行的组件创建好了它们的starter,你可以在这里查看这些starter的列表。
创建自己的Spring Boot Starter
如果你想要自己创建一个starter,那么基本上包含以下几步
- 创建一个starter项目,关于项目的命名你可以参考这里
- 创建一个ConfigurationProperties用于保存你的配置信息(如果你的项目不使用配置信息则可以跳过这一步,不过这种情况非常少见)
- 创建一个AutoConfiguration,引用定义好的配置信息;在AutoConfiguration中实现所有starter应该完成的操作,并且把这个类加入spring.factories配置文件中进行声明
- 打包项目,之后在一个SpringBoot项目中引入该项目依赖,然后就可以使用该starter了
我们来看一个例子(例子的完整代码位于https://github.com/RitterHou/learn-spring-boot-starter)
首先新建一个Maven项目,设置 pom.xml
文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>http-starter</artifactId>
<version>0.0.1-SNAPSHOT</version> <!-- 自定义starter都应该继承自该依赖 -->
<!-- 如果自定义starter本身需要继承其它的依赖,可以参考 https://stackoverflow.com/a/21318359 解决 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starters</artifactId>
<version>1.5.2.RELEASE</version>
</parent> <dependencies>
<!-- 自定义starter依赖此jar包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- lombok用于自动生成get、set方法 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
</dependencies> </project>
创建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中的数据确实被覆盖了。
Spring Boot Starters是什么?的更多相关文章
- Spring Boot Starters到底怎么回事?
前言 上周看了一篇.你一直在用的Spring Boot Starters究竟是怎么回事(https://www.cnblogs.com/fengzheng/p/10947585.html) 感觉终 ...
- Spring Boot Starters介绍
文章目录 Web Start Test Starter Data JPA Starter Mail Starter 结论 对于任何一个复杂项目来说,依赖关系都是一个非常需要注意和消息的方面,虽然重要, ...
- 54 个官方 Spring Boot Starters 出炉!别再重复造轮子了…….
在之前的文章,栈长介绍了 Spring Boot Starters,不清楚的可以点击链接进去看下. 前段时间 Spring Boot 2.4.0 也发布了,本文栈长再详细总结下最新的 Spring B ...
- Spring Boot Starters
Spring Boot Starters 摘自 https://www.nosuchfield.com/2017/10/15/Spring-Boot-Starters/ 2017-10-15 Spri ...
- Spring Boot Starters 列表
Spring Boot application starters 名称 描述 Pom spring-boot-starter 核心starter,包括自动配置支持,日志和YAML Pom spring ...
- Spring Boot Starters启动器
Starters是什么? Starters可以理解为启动器,它包含了一系列可以集成到应用里面的依赖包,你可以一站式集成Spring及其他技术,而不需要到处找示例代码和依赖包.如你想使用Spring J ...
- 你一直在用的 Spring Boot Starters 究竟是怎么回事
Spring Boot 对比 Spring MVC 最大的优点就是使用简单,约定大于配置.不会像之前用 Spring MVC 的时候,时不时被 xml 配置文件搞的晕头转向,冷不防还因为 xml 配置 ...
- Spring Boot Starters 究竟是怎么回事
Spring Boot 对比 Spring MVC 最大的优点就是使用简单,约定大于配置.不会像之前用 Spring MVC 的时候,时不时被 xml 配置文件搞的晕头转向,冷不防还因为 xml 配置 ...
- Sping Boot入门到实战之实战篇(二):一些常用功能的Spring Boot Starters
包含功能 阿里云消息服务MNS 阿里云消息队列服务(即时消息.延迟消息.事务消息) AOP日志 基于MyBatis通用Mapper及DRUID的数据库访问 dubbo支持 错误处理 七牛图片服务 re ...
随机推荐
- jquery.fn.extend() 与 $.jquery 作用及区别
原文:http://www.cnblogs.com/liu-l/p/3928373.html jQuery.extend()这个方法,主要是用来拓展个全局函数啦,例如$.ajax()这种,要不就是拓展 ...
- 编译驱动的Makefile解析
一个典型的编译驱动模块的Makefile文件如下所示: KERN_DIR = /root/driver/kernel obj-m += module_test.o all: make -C $(KER ...
- 五)Spring + Quartz 复杂业务的两个问题:获取Spring上下文 和 自动注入服务类
配置如下: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http:// ...
- ORA-00054、ORA-08002
https://docs.oracle.com/cd/B10501_01/server.920/a96525/e7500.htm ORA-00054 resource busy and acquire ...
- Oracle EBS不能正常启动的解决方案 > Jinitiator 乱码
问题1:使用IE浏览器(IE6 IE7 IE8)可以登录EBS,但在打开EBS的WIN Form界面里,IE自动关闭或报错,或是卡住不动 原因1: oracle EBS自带安装的JInitiator ...
- Intellij IDEA如何在一个窗口同时打开多个Maven项目
建立父目录,比如fatherProject,并将多个项目放入该父目录fatherProject下 File-Open...打开父目录fatherProject 引入pom.xml,打开Maven Pr ...
- linux服务器下配置多tomcat
车辆交易用的系统模块,正在做.老板要看看,以便车城那边的人提出意见.于是在服务器上再次增加一个tomcat. 以前是配置过的,配置过程其实很简单,这次太大意了,找了半天问题. 首先是拷贝一个tomca ...
- pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.
# 背景 安装pip后发现执行pip install pytest,提示下面错误 pip is configured with locations that require TLS/SSL, howe ...
- mysql5.7 column cannot be null
背景 独立测试环境安装了数据库,但安装的版本是mysql 5.7的版本,而研发用的是mysql5.6的版本,在执行某个数据库操作的提示,提示column “xxxx”cannot be null 问题 ...
- jdk动态代理 案例
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflec ...