一、前言

​  上篇文章我们已经聊了SpringBoot的启动过程中的各类扩展点,那么从http://start.spring.io上我们生成的demo项目中,到目前就剩下了maven工程的pom.xml还没有进行探索了,那么本文我们就来看看这里面到底都有啥,把大力出奇迹的常见spring-boot-starter来聊一聊,以便更好地使用SpringBoot.

二、SpringBoot项目的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>

<groupId>com.hafiz</groupId><artifactId>springboot-demo</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging>

<name>springboot-demo</name><description>Demo project for Spring Boot</description>

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.5.13.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent>

<properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version></properties>

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>

<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

​  我们可以看到所有的结构都是我们熟悉的。首先映入眼帘的是:<parent></parent>标签,熟悉Maven的朋友都知道,这个标签用来定义要继承的父pom的信息,它用来定义SpringBoot项目可能用到的依赖和插件声明以及一些资源文件声明,这样我们就可以在自己的SpringBoot项目中用到这些依赖或者插件的时候直接饮用,而不用指定版本号,正如我们上面看到的spring-boot-starter-webspring-boot-starter-test依赖以及spring-boot-maven-plugin插件一样,父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><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>1.5.13.RELEASE</version><relativePath>../../spring-boot-dependencies</relativePath></parent><artifactId>spring-boot-starter-parent</artifactId><packaging>pom</packaging><name>Spring Boot Starter Parent</name><description>Parent pom providing dependency and plugin management for applications        built with Maven</description><url>http://projects.spring.io/spring-boot/</url><organization><name>Pivotal Software, Inc.</name><url>http://www.spring.io</url></organization><properties><java.version>1.6</java.version><resource.delimiter>@</resource.delimiter> <!-- delimiter that doesn't clash with Spring ${} placeholders --><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><maven.compiler.source>${java.version}</maven.compiler.source><maven.compiler.target>${java.version}</maven.compiler.target></properties><dependencyManagement><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>${spring.version}</version><exclusions><exclusion><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId></exclusion></exclusions></dependency></dependencies></dependencyManagement><build><!-- Turn on filtering by default for application properties --><resources><resource><directory>${basedir}/src/main/resources</directory><filtering>true</filtering><includes><include>**/application*.yml</include><include>**/application*.yaml</include><include>**/application*.properties</include></includes></resource><resource><directory>${basedir}/src/main/resources</directory><excludes><exclude>**/application*.yml</exclude><exclude>**/application*.yaml</exclude><exclude>**/application*.properties</exclude></excludes></resource></resources><pluginManagement><plugins><!-- Apply more sensible defaults for user projects --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-failsafe-plugin</artifactId><executions><execution><goals><goal>integration-test</goal><goal>verify</goal></goals></execution></executions></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><configuration><archive><manifest><mainClass>${start-class}</mainClass><addDefaultImplementationEntries>true</addDefaultImplementationEntries></manifest></archive></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><configuration><includes><include>**/*Tests.java</include><include>**/*Test.java</include></includes><excludes><exclude>**/Abstract*.java</exclude></excludes></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-war-plugin</artifactId><configuration><failOnMissingWebXml>false</failOnMissingWebXml><archive><manifest><mainClass>${start-class}</mainClass><addDefaultImplementationEntries>true</addDefaultImplementationEntries></manifest></archive></configuration></plugin><plugin><groupId>org.codehaus.mojo</groupId><artifactId>exec-maven-plugin</artifactId><configuration><mainClass>${start-class}</mainClass></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-resources-plugin</artifactId><version>2.6</version><configuration><delimiters><delimiter>${resource.delimiter}</delimiter></delimiters><useDefaultDelimiters>false</useDefaultDelimiters></configuration></plugin><plugin><groupId>pl.project13.maven</groupId><artifactId>git-commit-id-plugin</artifactId><executions><execution><goals><goal>revision</goal></goals></execution></executions><configuration><verbose>true</verbose><dateFormat>yyyy-MM-dd'T'HH:mm:ssZ</dateFormat><generateGitPropertiesFile>true</generateGitPropertiesFile><generateGitPropertiesFilename>${project.build.outputDirectory}/git.properties</generateGitPropertiesFilename></configuration></plugin><!-- Support our own plugin --><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><executions><execution><goals><goal>repackage</goal></goals></execution></executions><configuration><mainClass>${start-class}</mainClass></configuration></plugin><!-- Support shade packaging (if the user does not want to use our plugin) --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-shade-plugin</artifactId><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>1.5.13.RELEASE</version></dependency></dependencies><configuration><keepDependenciesWithProvidedScope>true</keepDependenciesWithProvidedScope><createDependencyReducedPom>true</createDependencyReducedPom><filters><filter><artifact>*:*</artifact><excludes><exclude>META-INF/*.SF</exclude><exclude>META-INF/*.DSA</exclude><exclude>META-INF/*.RSA</exclude></excludes></filter></filters></configuration><executions><execution><phase>package</phase><goals><goal>shade</goal></goals><configuration><transformers><transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"><resource>META-INF/spring.handlers</resource></transformer><transformer implementation="org.springframework.boot.maven.PropertiesMergingResourceTransformer"><resource>META-INF/spring.factories</resource></transformer><transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"><resource>META-INF/spring.schemas</resource></transformer><transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/><transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"><mainClass>${start-class}</mainClass></transformer></transformers></configuration></execution></executions></plugin></plugins></pluginManagement></build></project>

  但是我们发现,该父pom文件还有自己的父pom,作用类似,不再详解,感兴趣的可以自己去翻阅源码。那么这样看来我们自己的SpringBoot项目中的pom.xml文件就剩下显眼的两个依赖以及一个插件了(没有指定版本号的原因前面已经解释了),那我们接下来就来聊一聊这些非常重要的spring-boot-starter依赖。

三、不可或缺的spring-boot-starter

​  我们从前面就知道了,SpringBoot能够如此方便便捷,其实都是得益于这些“开箱即用”的依赖模块,那SpringBoot设计者约定这些“开箱即用”的依赖模块的命名都以spring-boot-starter-开始,并且这些模块都位于org.springframework.boot包或者命名空间下面。我们也可以模仿者来实现自己的自动配置依赖模块,也已spring-boot-starter-开头,是不是就很"正宗"呢?(虽然SpringBoot官方不建议我们这样做,以免跟官方提供的混淆,但是其实我们使用自己的groupId,这样命名应该不是啥问题)。

​  这些starter其实都有约定好的默认配置,但是它也允许我们调整这些默认配置,以便完成定制化的需求,我们可以改变默认配置的常见方式有以下几种:

  • 命令行参数(Command Line Args)
  • 系统环境变量(Environment Variables)
  • 位于文件系统中的配置文件
  • 位于classpath中的配置文件
  • 固化到代码中的配置项

  这几种方式从上到下优先级从高到低排列,高优先级的配置会覆盖优先级低的配置。还有就是不管位于文件系统还是classpath中的配置文件,SpringBoot应用默认的文件名称都是application.properties,可以放在当前项目的根目录下或者名称为config的子目录下。

​  SpringBoot其实提供了很多这样的模块,我们就挑几个我们常用的这样的模块来解析,其他的大家就举一反三。以达到在工作和开发中灵活运用这些spring-boot-starter模块的效果。

1. spring-boot-starter-logging以及应用日志

 如果我们在maven依赖中添加了spring-boot-starter-logging:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-logging</artifactId></dependency>

  那也就意味着我们的SpringBoot应用自动使用logback作为日志框架,在启动的时候,由org.springframework.boot.logging.LoggingApplicationListener根据情况初始化并使用。默认情况下,SpringBoot已经给我们提供好了很多默认的日志配置,我们只需要将spring-boot-starter-logging作为依赖加入到你的SpringBoot应用就可以了,但是如果我们要对这些默认配置进行定制,可以有两种方式进行:

  • 遵守logback的约定,在classpath中使用定制化的logback.xml配置文件。

  • 在文件系统中任意一个地方提供自己的logback.xml配置文件,然后通过如下配置来application.properties中指定我们日志系统配置文件位置:

    logging.config=/{your config file location}}/logback.xml

如果我们已经习惯了log4j或log4j2,那我们只需要把spring-boot-starter-logging换成如下的starter就好。

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId></dependency>

2. 用于快速构建web应用的spring-boot-starter-web

​  现如今,我们在工作中大部分实际用的还是SpringMVC开发的web应用,SpringBoot当然贴心的为我们开发了一个web项目模块,让我们更加方便的开发web应用。maven依赖如下:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>

  这样我们就可以得到一个可以直接执行的Web应用,然后我们运行mvn spring-boot:run,就能直接启动一个基于嵌入式tomcat容器的Web应用了,然后就可以像这篇文章中定义controller来供用户访问了。但是呢,这简单的表象之下,其实却隐藏着很多约定,我们要把这些潜规则了解清楚才能更好地应用spring-boot-starter-web

2.1 项目结构的“潜规则”

​   传统的Java Web项目中,我们的静态文件以及页面模板都是放在src/main/webapp目录下,但是在SpringBoot应用中,这些文件被统一放在src/main/resources相应的子目录下:

  • src/main/resources/static目录用于存放各种静态资源,如:js、css、image等。
  • src/main/resources/template目录用于存放模板文件。

细心地我们会发现SpringBoot的web应用已经变成了jar包而再是war包,如果我们还是希望以war包的形式发布也是可以的。

2.2 SpringMVC框架层面的约定及定制

spring-boot-starter-web默认将为我们自动配置如下一些SpringMVC必要的组件:

  • ViewResolver,如:ContentNegotiatingViewResolverBeanNameViewResolver
  • Converter,如:GenericConverterFormatter等bean被注册到IoC容器。
  • 默认添加一系列HttpMessageConverter用于支持对Web请求和相应的类型转换。
  • 自动配置和注册MessageCodesResolver
  • 其他必要组件…
2.3 嵌入式Web容器的约定和定制

​  我们知道spring-boot-starter-web默认把嵌入式tomcat作为web容器来对外提供HTTP服务,默认使用8080端口对外监听和提供服务。这里我们可能会有两个疑问:

  • 我们不想使用默认的嵌入式tomcat容器怎么办?

    很简单,我们只需要引入spring-boot-starter-jettyspring-boot-starter-undertow依赖就能替代默认嵌入式tomcat容器了。

  • 我们想要把启动后提供服务的端口改掉怎么办?

    我们可以通过在配置文件中修改启动端口就可以了,如:

    server.port=9000

其实,spring-boot-starter-web提供了很多以server.作为前缀的配置以用来修改嵌入式容器的配置,如:

server.portserver.addressserver.ssl.*server.tomcat.*

那若这些还满足不了你,SpringBoot甚至都允许我们直接对嵌入式Web容器实例进行定制化,我们通过向IoC容器中注册一个EmbeddedServletContainerCustomizer类型的组件来实现:

package com.hafiz.springbootdemo;

import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;

/** * @author hafiz.zhang * @description: 自定义内嵌容器配置 * @date Created in 2018/6/10 12:09. */public class DemoEmbeddedTomcatCustomizer implements EmbeddedServletContainerCustomizer{@Overridepublic void customize(ConfigurableEmbeddedServletContainer container){        container.setPort(9111);        container.setContextPath("/demo");// ...    }}

如果还要再深入的定制,那就需要实现对应内嵌容器的Factory并注册到IoC容器:

  • TomcatEmbeddedServletContainerFactory
  • JettyEmbeddedServletContainerFactory
  • UndertowEmbeddedServletContainerFactory

  但是,我们几乎没有可能需要这样的定制化,也不建议这样的定制化,使用SpringBoot默认的spring-boot-starter-web提供的配置项列表已经很简单、很完整了。

3. 用于数据访问的spring-boot-starter-jdbc

  我们知道,现实中大多数的Java应用都需要访问数据库,那SpringBoot肯定不会放过这个组件,它会很贴心的为我们自动配置好相应的数据访问工具。我们只需要在pom.xml中添加以下依赖就好了:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency>

  这样,在我们没有配置任何DataSource的情况下,SpringBoot会默认为我们自动配置一个基于嵌入式数据的DataSource,这种自动配置适合于测试场景,生产环境不适合。大多数情况下,我们都会自己配置DataSource实例,或通过自动配置模块提供的配置参数对DataSource实例配置自定义的参数。

若我们的SpringBoot应用只依赖一个数据库,那我们直接使用自动配置模块提供的配置参数最方便快捷:

spring.datasource.url=jdbc:mysql://{db host}:{db port}/{db name}spring.datasource.username={db user name}spring.datasource.password={db password}

  有的小伙伴说了:那我自己配置一个DataSource行不行?答案是当然可以,SpringBoot会很智能的优先选择使用我们自己配置的这个DataSource,但是感觉多此一举!你要知道,SpringBoot除了自动帮我们配置DataSource以外,还自动帮我们配置了相应的JdbcTemplate以及DataSourceTransactionManager等相关的组件,我们只需要在需要使用的地方直接使用@Autowired注解引用就好了。

​  那SpringBoot是不是一直贴心呢?很明显不是的,如果我们的单个项目需要依赖和访问多个数据库,这个时候就不行了,就算是我们在ApplicationContext中配置了多个DataSource实例来访问多个数据库:

@Beanpublic DataSource dataSource1() throws Throwable{    DruidDataSource ds = new DruidDataSource();    ds.setUrl(...);    ds.setUsername(...);    ds.setPassword(...);// set other db settingreturn ds;}@Beanpublic DataSource dataSource2() throws Throwable{    DruidDataSource ds = new DruidDataSource();    ds.setUrl(...);    ds.setUsername(...);    ds.setPassword(...);// set other db settingreturn ds;}

启动项目时,你就会发现如下的异常:

No qualifying bean of type [javax.sql.DataSource] is defined: expected single matching bean but found 2...

那怎么解决这个问题呢?有两种方式:

  • 在SpringBoot的启动类上“动手脚”

    @SpringBootApplication(exclude = {  DataSourceAutoConfiguration.class,  DataSourceTransactionManagerAutoConfiguration.class})public class DemoSpringBootApplication{public static void main(String[] args){      SpringApplication.run(DemoSpringBootApplication.class, args);  }}

    这也就是说我们需要排除掉SpringBoot默认的DataSource的相关的自动配置。

  • 使用@primary注解

    那我们既要配置两个数据源,又要使用SpringBoot默认的DataSource,这时我们就可以为我们配置的两个DataSource中的任意一个使用@primary注解就可以了。

    @Bean@Primarypublic DataSource dataSource1() throws Throwable{  DruidDataSource ds = new DruidDataSource();  ds.setUrl(...);  ds.setUsername(...);  ds.setPassword(...);// set other db settingreturn ds;}@Beanpublic DataSource dataSource2() throws Throwable{  DruidDataSource ds = new DruidDataSource();  ds.setUrl(...);  ds.setUsername(...);  ds.setPassword(...);// set other db settingreturn ds;}

    除此之外,SpringBoot还提供了很多其他数据源访问相关的自动配置模块,如:spring-boot-starter-jpaspring-boot-starter-mongodb等。

四、总结

  除了本文我们介绍的常用的三个spring-boot-starter以外,SpringBoot还提供了很多别的starter,包括spring-boot-starter-aopspring-boot-starter-securityspring-boot-starter-actuator等等。我们通过本文举一反三,可以做到用的时候得心应手。棒!给自己一个赞~

spring-boot-starter大力出奇迹相关推荐

  1. 手把手教你定制标准 Spring Boot starter

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 写在前面 我们每次构建一个 Spring 应用程序时,我 ...

  2. 一个项目有两个pom_实现一个Spring Boot Starter超简单,读 Starter 源码也不在话下...

    Spring Boot 对比 Spring MVC 最大的优点就是使用简单,约定大于配置.不会像之前用 Spring MVC 的时候,时不时被 xml 配置文件搞的晕头转向,冷不防还因为 xml 配置 ...

  3. 自定义依赖注解无效_最详细的自定义Spring Boot Starter开发教程

    1.前言 随着Spring的日渐臃肿,为了简化配置.开箱即用.快速集成,Spring Boot 横空出世.目前已经成为 Java 目前最火热的框架了.平常我们用Spring Boot开发web应用.S ...

  4. 《SpringCloud超级入门》Spring Boot Starter的介绍及使用《七》

    目录 Spring Boot Starter项目创建 自动创建客户端 使用 Starter 使用注解开启 Starter 自动构建 使用配置开启 Starter 自动构建 配置 Starter 内容提 ...

  5. 实现一个 Spring Boot Starter 原来如此简单,读 Starter 源码也不在话下

    我是风筝,公众号「古时的风筝」,一个在程序圈混迹多年,主业 Java,另外 Python.React 也玩儿的 6 的斜杠开发者.现已转行程序员鼓励师 Spring Cloud 系列文章已经完成,可以 ...

  6. 一个简易上手的短信服务Spring Boot Starter,连傻瓜都会!

    作 者:jackieonway 来 源:jianshu.com/u/36510c75d37c 短信服务在用户注册.登录.找回密码等相关操作中,可以让用户使用更加便捷,越来越多的公司都采用短信验证的方式 ...

  7. 快速开发一个自定义 Spring Boot Starter ,希望你也会

    来源:http://t.cn/Ai9li9fC 众所周知,Spring Boot由众多Starter组成,随着版本的推移Starter家族成员也与日俱增.在传统Maven项目中通常将一些层.组件拆分为 ...

  8. 自定义 Spring Boot Starter

    一.引言 什么是Spring Boot Starter呢?我们直接来看看官网是怎么介绍的吧. Starters are a set of convenient dependency descripto ...

  9. Spring boot starter

    1:Spring boot starter及项目中的类似运用 1:Spring boot starter的两种方式 引入pom文件,自动管理jar版本 根据spring.factories配置文件,加 ...

  10. Spring Boot Starter 常用列表

    文章目录 1.美图 2.常用列表 3.源码中的starters 1.美图 2.常用列表 以下为常⽤用的 Spring Boot Starter 列列表. 名称 描述 Pom spring-boot-s ...

最新文章

  1. 研究能力培养的阶梯: 盐趣一对一科研项目
  2. SSL/TLS 协议简介与实例分析
  3. Linux 系统之软件管理
  4. pythonandroid自动化测试仪器_使用Python进行Android自动化测试
  5. Windows Live Writer 的昨日荣光
  6. linux Pci字符驱动基本加载流程
  7. 5001 boost之bind库函数
  8. 设计师交流分享社区|灵感并非凭空得来,积累在集设网
  9. input file multiple 配合springmvc实现多文件上传
  10. The Linux Process Principle, PID、PGID、PPID、SID、TID、TTY
  11. 个人技能总结7--Apache服务器反向代理,负载均衡,热备份+Tomcat配置
  12. IPFS python api 示例
  13. php基础之字符串和数组的相互转换及其常用属性(与js相对应的属性 比较)
  14. 手机上编写Java程序的软件
  15. matlab如何求无穷多项乘积的极限,求极限方法小结
  16. UART通信协议(一)比特率和波特率
  17. 推荐系统之ALS算法详解
  18. 编程中,有哪些好的习惯一开始就值得坚持?
  19. python apply函数_Python中apply函数的用法实例教程
  20. 【Git】git checkout

热门文章

  1. 关于html的简单学习-简单无脑简历
  2. transformer模型学习路线
  3. centos安装配置OPEN*PN
  4. OpenVpnCentos7脚本
  5. 如何使FRAM MCU速度更快所需功耗最低
  6. 超越信标链:Eth2的下一步是什么?
  7. python 迭代器和惰性计算、函数式编程基础
  8. 用css怎样实现波浪线,css如何实现波浪线和立方体
  9. 使用ScriptableObjects制作有趣的东西
  10. 微信支付宝开启刷脸支付的研发工作和商用探索