Spring boot参考指南

来源:互联网 发布:js click 编辑:程序博客网 时间:2024/05/29 14:54

介绍
转载自:https://www.gitbook.com/book/qbgbook/spring-boot-reference-guide-zh/details
带目录浏览地址:http://www.maoyupeng.com/spring-boot-api.html

1.Spring Boot文档
本节提供一个Spring Boot参考文档的简明概述。你可以把它作为文档其余部分的导航。你可以从头到尾依次阅读该参考指南,或跳过你不感兴趣的章节。

1.1关于本文档
Spring Boot参考指南有html,pdf和epub形式的文档。在docs.spring.io/spring-boot/docs/current/reference可获取到最新的副本。

在对副本不收取任何费用,并且不管是打印还是电子版每个副本都包含版权声明的情况下,你可以自己使用本文档副本,也可以分发给其他人。

开始
如果你想从总体上对Spring Boot或Spring入门,本章节就是为你准备的!在这里,我们将回答基本的”what?”,”how?”和”why?”问题。你会发现一个温雅的Spring Boot介绍及安装指南。然后我们构建第一个Spring Boot应用,并讨论一些我们需要遵循的核心原则。

2.1 Spring Boot介绍
Spring Boot使开发独立的,产品级别的基于Spring的应用变得非常简单,你只需”just run”。 我们为Spring平台及第三方库提供开箱即用的设置,这样你就可以有条不紊地开始。多数Spring Boot应用需要很少的Spring配置。

你可以使用Spring Boot创建Java应用,并使用java -jar启动它或采用传统的war部署方式。我们也提供了一个运行”spring脚本”的命令行工具。

我们主要的目标是:

为所有的Spring开发提供一个从根本上更快的和广泛使用的入门经验。
开箱即用,但你可以通过不采用默认设置来摆脱这种方式。
提供一系列大型项目常用的非功能性特征(比如,内嵌服务器,安全,指标,健康检测,外部化配置)。
绝对不需要代码生成及XML配置。
2.2 系统要求
默认情况下,Spring Boot 1.3.0.BUILD-SNAPSHOT 需要Java7和Spring框架4.1.3或以上。你可以在Java6下使用Spring Boot,不过需要添加额外配置。具体参考Section 73.9, “How to use Java 6” 。构建环境明确支持的有Maven(3.2+)和Gradle(1.12+)。

注:尽管你可以在Java6或Java7环境下使用Spring Boot,通常我们建议你如果可能的话就使用Java8。

2.2.1 Servlet容器
下列内嵌容器支持开箱即用(out of the box):

名称 Servlet版本 Java版本
Tomcat 8 3.1 Java 7+
Tomcat 7 3.0 Java 6+
Jetty 9 3.1 Java 7+
Jetty 8 3.0 Java 6+
Undertow 1.1 3.1 Java 7+
你也可以将Spring Boot应用部署到任何兼容Servlet 3.0+的容器。

2.3 Spring Boot安装
Spring Boot可以跟典型的Java开发工具一块使用或安装为一个命令行工具。不管怎样,你将需要安装Java SDK v1.6 或更高版本。在开始之前,你需要检查下当前安装的Java版本:

$ java -version
如果你是一个Java新手,或你只是想体验一下Spring Boot,你可能想先尝试Spring Boot CLI,否则继续阅读经典地安装指南。

注:尽管Spring Boot兼容Java 1.6,如果可能的话,你应该考虑使用Java最新版本。

2.3.1 为Java开发者准备的安装指南
你可以像使用其他任何标准Java库那样使用Spring Boot,只需简单地在你的classpath下包含正确的spring-boot-*.jar文件。Spring Boot不需要集成任何特殊的工具,所以你可以使用任何IDE或文本编辑器;Spring Boot应用也没有什么特殊之处,所以你可以像任何其他Java程序那样运行和调试。

尽管你可以拷贝Spring Boot jars,不过,我们通常推荐你使用一个支持依赖管理的构建工具(比如Maven或Gradle)。

2.3.1.1 Maven安装
Spring Boot兼容Apache Maven 3.2或更高版本。如果没有安装Maven,你可以参考maven.apache.org指南。

注:在很多操作系统上,你可以通过一个包管理器安装Maven。如果你是一个OSX Homebrew用户,可以尝试brew install maven。Ubuntu用户可以运行sudo apt-get install maven。

Spring Boot依赖的groupId为org.springframework.boot。通常你的Maven POM文件需要继承spring-boot-starter-parent,然后声明一个或多个“Starter POMs”依赖。Spring Boot也提供了一个用于创建可执行jars的Maven插件。

下面是一个典型的pom.xml文件:

Available Springboot Versions

  • dev
  • 1.3.0.BUILD-SNAPSHOT

================================================================================
+ - local version
* - installed

> - currently in use

2.3.2.3 使用OSX Homebrew进行安装
如果你的环境是Mac,并使用Homebrew,想要安装Spring Boot CLI只需如下操作:

brewtappivotal/tap brew install springboot
Homebrew将把spring安装到/usr/local/bin下。

注:如果该方案不可用,可能是因为你的brew版本太老了。你只需执行brew update并重试即可。

2.3.2.4 使用MacPorts进行安装
如果你的环境是Mac,并使用MacPorts,想要安装Spring Boot CLI只需如下操作:

$ sudo port install spring-boot-cli
2.3.2.5 命令行实现
Spring Boot CLI启动脚本为BASH和zsh shells提供完整的命令行实现。你可以在任何shell中source脚本(名称也是spring),或将它放到你个人或系统范围的bash实现初始化中。在一个Debian系统里,系统范围的脚本位于/shell-completion/bash下,当一个新的shell启动时该目录下的所有脚本都被执行。想要手动运行该脚本,例如,你已经使用GVM进行安装了:

. /.gvm/springboot/current/shellcompletion/bash/spring spring
grab help jar run test version
注:如果你使用Homebrew或MacPorts安装Spring Boot CLI,命令行实现脚本会自动注册到你的shell。

2.3.2.6 Spring CLI示例快速入门
下面是一个相当简单的web应用,你可以用它测试你的安装是否成功。创建一个名叫app.groovy的文件:

@RestController
class ThisWillActuallyRun {

@RequestMapping("/")String home() {    "Hello World!"}

}
然后简单地从一个shell中运行它:

$ spring run app.groovy
注:当你首次运行该应用时将会花费一点时间,因为需要下载依赖。后续运行将会快很多。

在你最喜欢的浏览器中打开localhost:8080,然后你应该看到以下输出:

Hello World!
2.3.3 从Spring Boot早期版本升级
如果你正在升级一个Spring Boot早期版本,查看下放在project wiki上的”release notes”。你会发现每次发布的更新指南和一个”new and noteworthy”特性列表。

想要升级一个已安装的CLI,你需要使用合适的包管理命令(例如,brew upgrade),或如果你是手动安装CLI,按照standard instructions操作并记得更新你的PATH环境变量以移除任何老的引用。

2.3.4 开发你的第一个Spring Boot应用
让我们使用Java开发一个简单的”Hello World!” web应用,来强调下Spring Boot的一些关键特性。我们将使用Maven构建该项目,因为大多数IDEs都支持它。

注:spring.io网站包含很多使用Spring Boot的”入门”指南。如果你正在找特定问题的解决方案,可以先去那瞅瞅。

在开始前,你需要打开一个终端,检查是否安装可用的Java版本和Maven:

$ java -version
java version “1.7.0_51”
Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)

$ mvn -v
Apache Maven 3.2.3 (33f8c3e1027c3ddde99d3cdebad2656a31e8fdf4; 2014-08-11T13:58:10-07:00)
Maven home: /Users/user/tools/apache-maven-3.1.1
Java version: 1.7.0_51, vendor: Oracle Corporation
注:该示例需要创建自己的文件夹。后续的操作假设你已创建一个合适的文件夹,并且它是你的“当前目录”。

2.3.5 创建POM
我们需要以创建一个Maven pom.xml文件作为开始。该pom.xml是用来构建项目的处方。打开你最喜欢的文本编辑器,然后添加以下内容:

address: 192.168.1.100

spring:
profiles: development
server:

address: 127.0.0.1

spring:
profiles: production
server:
address: 192.168.1.120
在上面的例子中,如果development配置被激活,那server.address属性将是127.0.0.1。如果development和production配置(profiles)没有启用,则该属性的值将是192.168.1.100。

4.2.6.4 YAML缺点
YAML文件不能通过@PropertySource注解加载。所以,在这种情况下,如果需要使用@PropertySource注解的方式加载值,那就要使用properties文件。

4.2.7 类型安全的配置属性
使用@Value(“${property}”)注解注入配置属性有时可能比较笨重,特别是需要使用多个properties或你的数据本身有层次结构。为了控制和校验你的应用配置,Spring Boot提供一个允许强类型beans的替代方法来使用properties。

示例:

@Component
@ConfigurationProperties(prefix=”connection”)
public class ConnectionSettings {
private String username;
private InetAddress remoteAddress;
// … getters and setters
}
当@EnableConfigurationProperties注解应用到你的@Configuration时,任何被@ConfigurationProperties注解的beans将自动被Environment属性配置。这种风格的配置特别适合与SpringApplication的外部YAML配置进行配合使用。

application.yml

connection:
username: admin
remoteAddress: 192.168.1.1

additional configuration as required

为了使用@ConfigurationProperties beans,你可以使用与其他任何bean相同的方式注入它们。

@Service
public class MyService {
@Autowired
private ConnectionSettings connection;
//…
@PostConstruct
public void openConnection() {
Server server = new Server();
this.connection.configure(server);
}
}
你可以通过在@EnableConfigurationProperties注解中直接简单的列出属性类来快捷的注册@ConfigurationProperties bean的定义。

@Configuration
@EnableConfigurationProperties(ConnectionSettings.class)
public class MyConfiguration {
}
注:使用@ConfigurationProperties能够产生可被IDEs使用的元数据文件。具体参考Appendix B, Configuration meta-data。

4.2.7.1 第三方配置
正如使用@ConfigurationProperties注解一个类,你也可以在@Bean方法上使用它。当你需要绑定属性到不受你控制的第三方组件时,这种方式非常有用。

为了从Environment属性配置一个bean,将@ConfigurationProperties添加到它的bean注册过程:

@ConfigurationProperties(prefix = “foo”)
@Bean
public FooComponent fooComponent() {

}
和上面ConnectionSettings的示例方式相同,任何以foo为前缀的属性定义都会被映射到FooComponent上。

4.2.7.2 松散的绑定(Relaxed binding)
Spring Boot使用一些宽松的规则用于绑定Environment属性到@ConfigurationProperties beans,所以Environment属性名和bean属性名不需要精确匹配。常见的示例中有用的包括虚线分割(比如,context–path绑定到contextPath)和将环境属性转为大写字母(比如,PORT绑定port)。

示例:

@Component
@ConfigurationProperties(prefix=”person”)
public class ConnectionSettings {
private String firstName;
}
下面的属性名都能用于上面的@ConfigurationProperties类:

属性 说明
person.firstName 标准驼峰规则
person.first-name 虚线表示,推荐用于.properties和.yml文件中
PERSON_FIRST_NAME 大写形式,使用系统环境变量时推荐
Spring会尝试强制外部的应用属性在绑定到@ConfigurationProperties beans时类型是正确的。如果需要自定义类型转换,你可以提供一个ConversionService bean(bean id为conversionService)或自定义属性编辑器(通过一个CustomEditorConfigurer bean)。

4.2.7.3 @ConfigurationProperties校验
Spring Boot将尝试校验外部的配置,默认使用JSR-303(如果在classpath路径中)。你可以轻松的为你的@ConfigurationProperties类添加JSR-303 javax.validation约束注解:

@Component
@ConfigurationProperties(prefix=”connection”)
public class ConnectionSettings {
@NotNull
private InetAddress remoteAddress;
// … getters and setters
}
你也可以通过创建一个叫做configurationPropertiesValidator的bean来添加自定义的Spring Validator。

注:spring-boot-actuator模块包含一个暴露所有@ConfigurationProperties beans的端点。简单地将你的web浏览器指向/configprops或使用等效的JMX端点。具体参考Production ready features。

4.3 Profiles
Spring Profiles提供了一种隔离应用程序配置的方式,并让这些配置只能在特定的环境下生效。任何@Component或@Configuration都能被@Profile标记,从而限制加载它的时机。

@Configuration
@Profile(“production”)
public class ProductionConfiguration {
// …
}
以正常的Spring方式,你可以使用一个spring.profiles.active的Environment属性来指定哪个配置生效。你可以使用平常的任何方式来指定该属性,例如,可以将它包含到你的application.properties中:

spring.profiles.active=dev,hsqldb
或使用命令行开关:

–spring.profiles.active=dev,hsqldb
4.3.1 添加激活的配置(profiles)
spring.profiles.active属性和其他属性一样都遵循相同的排列规则,最高的PropertySource获胜。也就是说,你可以在application.properties中指定生效的配置,然后使用命令行开关替换它们。

有时,将特定的配置属性添加到生效的配置中而不是替换它们是有用的。spring.profiles.include属性可以用来无条件的添加生效的配置。SpringApplication的入口点也提供了一个用于设置额外配置的Java API(比如,在那些通过spring.profiles.active属性生效的配置之上):参考setAdditionalProfiles()方法。

示例:当一个应用使用下面的属性,并用–spring.profiles.active=prod开关运行,那proddb和prodmq配置也会生效:


my.property: fromyamlfile

spring.profiles: prod
spring.profiles.include: proddb,prodmq
注:spring.profiles属性可以定义到一个YAML文档中,用于决定什么时候该文档被包含进配置中。具体参考Section 63.6, “Change configuration depending on the environment”

4.3.2 以编程方式设置profiles
在应用运行前,你可以通过调用SpringApplication.setAdditionalProfiles(…)方法,以编程的方式设置生效的配置。使用Spring的ConfigurableEnvironment接口激动配置也是可行的。

4.3.3 Profile特定配置文件
application.properties(或application.yml)和通过@ConfigurationProperties引用的文件这两种配置特定变种都被当作文件来加载的,具体参考Section 23.3, “Profile specific properties”。

4.5 日志
Spring Boot内部日志系统使用的是Commons Logging,但开放底层的日志实现。默认为会Java Util Logging, Log4J, Log4J2和Logback提供配置。每种情况下都会预先配置使用控制台输出,也可以使用可选的文件输出。

默认情况下,如果你使用’Starter POMs’,那么就会使用Logback记录日志。为了确保那些使用Java Util Logging, Commons Logging, Log4J或SLF4J的依赖库能够正常工作,正确的Logback路由也被包含进来。

注:如果上面的列表看起来令人困惑,不要担心,Java有很多可用的日志框架。通常,你不需要改变日志依赖,Spring Boot默认的就能很好的工作。

4.4.1 日志格式
Spring Boot默认的日志输出格式如下:

2014-03-05 10:57:51.112 INFO 45469 — [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/7.0.52
2014-03-05 10:57:51.253 INFO 45469 — [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2014-03-05 10:57:51.253 INFO 45469 — [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1358 ms
2014-03-05 10:57:51.698 INFO 45469 — [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: ‘dispatcherServlet’ to [/]
2014-03-05 10:57:51.702 INFO 45469 — [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: ‘hiddenHttpMethodFilter’ to: [/*]
输出的节点(items)如下:

日期和时间 - 精确到毫秒,且易于排序。
日志级别 - ERROR, WARN, INFO, DEBUG 或 TRACE。
Process ID。
一个用于区分实际日志信息开头的—分隔符。
线程名 - 包括在方括号中(控制台输出可能会被截断)。
日志名 - 通常是源class的类名(缩写)。
日志信息。
4.4.2 控制台输出
默认的日志配置会在写日志消息时将它们回显到控制台。默认,ERROR, WARN和INFO级别的消息会被记录。可以在启动应用时,通过–debug标识开启控制台的DEBUG级别日志记录。

$ java -jar myapp.jar –debug
如果你的终端支持ANSI,为了增加可读性将会使用彩色的日志输出。你可以设置spring.output.ansi.enabled为一个支持的值来覆盖自动检测。

4.4.3 文件输出
默认情况下,Spring Boot只会将日志记录到控制台而不会写进日志文件。如果除了输出到控制台你还想写入到日志文件,那你需要设置logging.file或logging.path属性(例如在你的application.properties中)。

下表显示如何组合使用logging.*:

logging.file logging.path 示例 描述
(none) (none) 只记录到控制台
Specific file (none) my.log 写到特定的日志文件里,名称可以是一个精确的位置或相对于当前目录
(none) Specific folder /var/log 写到特定文件夹下的spring.log里,名称可以是一个精确的位置或相对于当前目录
日志文件每达到10M就会被轮换(分割),和控制台一样,默认记录ERROR, WARN和INFO级别的信息。

4.4.4 日志级别
所有支持的日志系统在Spring的Environment(例如在application.properties里)都有通过’logging.level.*=LEVEL’(’LEVEL’是TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF中的一个)设置的日志级别。

示例:application.properties

logging.level.org.springframework.web: DEBUG
logging.level.org.hibernate: ERROR
4.4.5 自定义日志配置
通过将适当的库添加到classpath,可以激活各种日志系统。然后在classpath的根目录(root)或通过Spring Environment的logging.config属性指定的位置提供一个合适的配置文件来达到进一步的定制(注意由于日志是在ApplicationContext被创建之前初始化的,所以不可能在Spring的@Configuration文件中,通过@PropertySources控制日志。系统属性和平常的Spring Boot外部配置文件能正常工作)。

根据你的日志系统,下面的文件会被加载:

日志系统 定制
Logback logback.xml
Log4j log4j.properties或log4j.xml
Log4j2 log4j2.xml
JDK (Java Util Logging) logging.properties
为了帮助定制一些其他的属性,从Spring的Envrionment转换到系统属性:

Spring Environment System Property 评价
logging.file LOG_FILE 如果定义,在默认的日志配置中使用
logging.path LOG_PATH 如果定义,在默认的日志配置中使用
PID PID 当前的处理进程(process)ID(如果能够被发现且还没有作为操作系统环境变量被定义)
所有支持的日志系统在解析它们的配置文件时都能查询系统属性。具体可以参考spring-boot.jar中的默认配置。

注:在运行可执行的jar时,Java Util Logging有类加载问题,我们建议你尽可能避免使用它。

4.5 开发web应用
Spring Boot非常适合开发web应用程序。你可以使用内嵌的Tomcat,Jetty或Undertow轻轻松松地创建一个HTTP服务器。大多数的web应用都使用spring-boot-starter-web模块进行快速搭建和运行。

4.5.1 Spring Web MVC 框架
Spring Web MVC框架(通常简称为”Spring MVC”)是一个富”模型,视图,控制器”的web框架。 Spring MVC允许你创建特定的@Controller或@RestController beans来处理传入的HTTP请求。 使用@RequestMapping注解可以将控制器中的方法映射到相应的HTTP请求。

示例:

@RestController
@RequestMapping(value=”/users”)
public class MyRestController {

@RequestMapping(value="/{user}", method=RequestMethod.GET)public User getUser(@PathVariable Long user) {    // ...}@RequestMapping(value="/{user}/customers", method=RequestMethod.GET)List<Customer> getUserCustomers(@PathVariable Long user) {    // ...}@RequestMapping(value="/{user}", method=RequestMethod.DELETE)public User deleteUser(@PathVariable Long user) {    // ...}

}
4.5.1.1 Spring MVC自动配置
Spring Boot为Spring MVC提供适用于多数应用的自动配置功能。在Spring默认基础上,自动配置添加了以下特性:

引入ContentNegotiatingViewResolver和BeanNameViewResolver beans。
对静态资源的支持,包括对WebJars的支持。
自动注册Converter,GenericConverter,Formatter beans。
对HttpMessageConverters的支持。
自动注册MessageCodeResolver。
对静态index.html的支持。
对自定义Favicon的支持。
如果想全面控制Spring MVC,你可以添加自己的@Configuration,并使用@EnableWebMvc对其注解。如果想保留Spring Boot MVC的特性,并只是添加其他的MVC配置(拦截器,formatters,视图控制器等),你可以添加自己的WebMvcConfigurerAdapter类型的@Bean(不使用@EnableWebMvc注解)。

4.5.1.2 HttpMessageConverters
Spring MVC使用HttpMessageConverter接口转换HTTP请求和响应。合理的缺省值被包含的恰到好处(out of the box),例如对象可以自动转换为JSON(使用Jackson库)或XML(如果Jackson XML扩展可用则使用它,否则使用JAXB)。字符串默认使用UTF-8编码。

如果需要添加或自定义转换器,你可以使用Spring Boot的HttpMessageConverters类:

import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
import org.springframework.context.annotation.*;
import org.springframework.http.converter.*;

@Configuration
public class MyConfiguration {

@Beanpublic HttpMessageConverters customConverters() {    HttpMessageConverter<?> additional = ...    HttpMessageConverter<?> another = ...    return new HttpMessageConverters(additional, another);}

}
任何在上下文中出现的HttpMessageConverter bean将会添加到converters列表,你可以通过这种方式覆盖默认的转换器(converters)。

4.5.1.3 MessageCodesResolver
Spring MVC有一个策略,用于从绑定的errors产生用来渲染错误信息的错误码:MessageCodesResolver。如果设置spring.mvc.message-codes-resolver.format属性为PREFIX_ERROR_CODE或POSTFIX_ERROR_CODE(具体查看DefaultMessageCodesResolver.Format枚举值),Spring Boot会为你创建一个MessageCodesResolver。

4.5.1.4 静态内容
默认情况下,Spring Boot从classpath下一个叫/static(/public,/resources或/META-INF/resources)的文件夹或从ServletContext根目录提供静态内容。这使用了Spring MVC的ResourceHttpRequestHandler,所以你可以通过添加自己的WebMvcConfigurerAdapter并覆写addResourceHandlers方法来改变这个行为(加载静态文件)。

在一个单独的web应用中,容器默认的servlet是开启的,如果Spring决定不处理某些请求,默认的servlet作为一个回退(降级)将从ServletContext根目录加载内容。大多数时候,这不会发生(除非你修改默认的MVC配置),因为Spring总能够通过DispatcherServlet处理请求。

此外,上述标准的静态资源位置有个例外情况是Webjars内容。任何在/webjars/**路径下的资源都将从jar文件中提供,只要它们以Webjars的格式打包。

注:如果你的应用将被打包成jar,那就不要使用src/main/webapp文件夹。尽管该文件夹是一个共同的标准,但它仅在打包成war的情况下起作用,并且如果产生一个jar,多数构建工具都会静悄悄的忽略它。

4.5.1.5 模板引擎
正如REST web服务,你也可以使用Spring MVC提供动态HTML内容。Spring MVC支持各种各样的模板技术,包括Velocity, FreeMarker和JSPs。很多其他的模板引擎也提供它们自己的Spring MVC集成。

Spring Boot为以下的模板引擎提供自动配置支持:

FreeMarker
Groovy
Thymeleaf
Velocity
注:如果可能的话,应该忽略JSPs,因为在内嵌的servlet容器使用它们时存在一些已知的限制。

当你使用这些引擎的任何一种,并采用默认的配置,你的模板将会从src/main/resources/templates目录下自动加载。

注:IntelliJ IDEA根据你运行应用的方式会对classpath进行不同的整理。在IDE里通过main方法运行你的应用跟从Maven或Gradle或打包好的jar中运行相比会导致不同的顺序。这可能导致Spring Boot不能从classpath下成功地找到模板。如果遇到这个问题,你可以在IDE里重新对classpath进行排序,将模块的类和资源放到第一位。或者,你可以配置模块的前缀为classpath*:/templates/,这样会查找classpath下的所有模板目录。

4.5.1.6 错误处理
Spring Boot默认提供一个/error映射用来以合适的方式处理所有的错误,并且它在servlet容器中注册了一个全局的 错误页面。对于机器客户端(相对于浏览器而言,浏览器偏重于人的行为),它会产生一个具有详细错误,HTTP状态,异常信息的JSON响应。对于浏览器客户端,它会产生一个白色标签样式(whitelabel)的错误视图,该视图将以HTML格式显示同样的数据(可以添加一个解析为erro的View来自定义它)。为了完全替换默认的行为,你可以实现ErrorController,并注册一个该类型的bean定义,或简单地添加一个ErrorAttributes类型的bean以使用现存的机制,只是替换显示的内容。

如果在某些条件下需要比较多的错误页面,内嵌的servlet容器提供了一个统一的Java DSL(领域特定语言)来自定义错误处理。 示例:

@Bean
public EmbeddedServletContainerCustomizer containerCustomizer(){
return new MyCustomizer();
}

// …
private static class MyCustomizer implements EmbeddedServletContainerCustomizer {
@Override
public void customize(ConfigurableEmbeddedServletContainer container) {
container.addErrorPages(new ErrorPage(HttpStatus.BAD_REQUEST, “/400”));
}
}
你也可以使用常规的Spring MVC特性来处理错误,比如@ExceptionHandler方法和@ControllerAdvice。ErrorController将会捡起任何没有处理的异常。

N.B. 如果你为一个路径注册一个ErrorPage,最终被一个过滤器(Filter)处理(对于一些非Spring web框架,像Jersey和Wicket这很常见),然后过滤器需要显式注册为一个ERROR分发器(dispatcher)。

@Bean
public FilterRegistrationBean myFilter() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new MyFilter());

registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
return registration;
}
注:默认的FilterRegistrationBean没有包含ERROR分发器类型。

4.5.1.7 Spring HATEOAS
如果你正在开发一个使用超媒体的RESTful API,Spring Boot将为Spring HATEOAS提供自动配置,这在多数应用中都工作良好。自动配置替换了对使用@EnableHypermediaSupport的需求,并注册一定数量的beans来简化构建基于超媒体的应用,这些beans包括一个LinkDiscoverer和配置好的用于将响应正确编排为想要的表示的ObjectMapper。ObjectMapper可以根据spring.jackson.*属性或一个存在的Jackson2ObjectMapperBuilder bean进行自定义。

通过使用@EnableHypermediaSupport,你可以控制Spring HATEOAS的配置。注意这会禁用上述的对ObjectMapper的自定义。

4.5.2 JAX-RS和Jersey
如果喜欢JAX-RS为REST端点提供的编程模型,你可以使用可用的实现替代Spring MVC。如果在你的应用上下文中将Jersey 1.x和Apache Celtix的Servlet或Filter注册为一个@Bean,那它们工作的相当好。Jersey 2.x有一些原生的Spring支持,所以我们会在Spring Boot为它提供自动配置支持,连同一个启动器(starter)。

想要开始使用Jersey 2.x只需要加入spring-boot-starter-jersey依赖,然后你需要一个ResourceConfig类型的@Bean,用于注册所有的端点(endpoints)。

@Component
public class JerseyConfig extends ResourceConfig {
public JerseyConfig() {
register(Endpoint.class);
}
}
所有注册的端点都应该被@Components和HTTP资源annotations(比如@GET)注解。

@Component
@Path(“/hello”)
public class Endpoint {
@GET
public String message() {
return “Hello”;
}
}
由于Endpoint是一个Spring组件(@Component),所以它的生命周期受Spring管理,并且你可以使用@Autowired添加依赖及使用@Value注入外部配置。Jersey servlet将被注册,并默认映射到/*。你可以将@ApplicationPath添加到ResourceConfig来改变该映射。

默认情况下,Jersey将在一个ServletRegistrationBean类型的@Bean中被设置成名称为jerseyServletRegistration的Servlet。通过创建自己的相同名称的bean,你可以禁止或覆盖这个bean。你也可以通过设置spring.jersey.type=filter来使用一个Filter代替Servlet(在这种情况下,被覆盖或替换的@Bean是jerseyFilterRegistration)。该servlet有@Order属性,你可以通过spring.jersey.filter.order进行设置。不管是Servlet还是Filter注册都可以使用spring.jersey.init.*定义一个属性集合作为初始化参数传递过去。

这里有一个Jersey示例,你可以查看如何设置相关事项。

4.5.3 内嵌servlet容器支持
Spring Boot支持内嵌的Tomcat, Jetty和Undertow服务器。多数开发者只需要使用合适的’Starter POM’来获取一个完全配置好的实例即可。默认情况下,内嵌的服务器会在8080端口监听HTTP请求。

4.5.3.1 Servlets和Filters
当使用内嵌的servlet容器时,你可以直接将servlet和filter注册为Spring的beans。在配置期间,如果你想引用来自application.properties的值,这是非常方便的。默认情况下,如果上下文只包含单一的Servlet,那它将被映射到根路径(/)。在多Servlet beans的情况下,bean的名称将被用作路径的前缀。过滤器会被映射到/*。

如果基于约定(convention-based)的映射不够灵活,你可以使用ServletRegistrationBean和FilterRegistrationBean类实现完全的控制。如果你的bean实现了ServletContextInitializer接口,也可以直接注册它们。

4.5.3.2 EmbeddedWebApplicationContext
Spring Boot底层使用了一个新的ApplicationContext类型,用于对内嵌servlet容器的支持。EmbeddedWebApplicationContext是一个特殊类型的WebApplicationContext,它通过搜索一个单一的EmbeddedServletContainerFactory bean来启动自己。通常,TomcatEmbeddedServletContainerFactory,JettyEmbeddedServletContainerFactory或UndertowEmbeddedServletContainerFactory将被自动配置。

注:你通常不需要知道这些实现类。大多数应用将被自动配置,并根据你的行为创建合适的ApplicationContext和EmbeddedServletContainerFactory。

4.5.3.3 自定义内嵌servlet容器
常见的Servlet容器设置可以通过Spring Environment属性进行配置。通常,你会把这些属性定义到application.properties文件中。 常见的服务器设置包括:

server.port - 进来的HTTP请求的监听端口号
server.address - 绑定的接口地址
server.sessionTimeout - session超时时间
具体参考ServerProperties。

编程方式的自定义
如果需要以编程的方式配置内嵌的servlet容器,你可以注册一个实现EmbeddedServletContainerCustomizer接口的Spring bean。EmbeddedServletContainerCustomizer提供对ConfigurableEmbeddedServletContainer的访问,ConfigurableEmbeddedServletContainer包含很多自定义的setter方法。

import org.springframework.boot.context.embedded.*;
import org.springframework.stereotype.Component;

@Component
public class CustomizationBean implements EmbeddedServletContainerCustomizer {
@Override
public void customize(ConfigurableEmbeddedServletContainer container) {
container.setPort(9000);
}
}
直接自定义ConfigurableEmbeddedServletContainer
如果上面的自定义手法过于受限,你可以自己注册TomcatEmbeddedServletContainerFactory,JettyEmbeddedServletContainerFactory或UndertowEmbeddedServletContainerFactory。

@Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
factory.setPort(9000);
factory.setSessionTimeout(10, TimeUnit.MINUTES);
factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, “/notfound.html”);
return factory;
}
很多可选的配置都提供了setter方法,也提供了一些受保护的钩子方法以满足你的某些特殊需求。具体参考相关文档。

4.5.3.4 JSP的限制
在内嵌的servlet容器中运行一个Spring Boot应用时(并打包成一个可执行的存档archive),容器对JSP的支持有一些限制。

tomcat只支持war的打包方式,不支持可执行的jar。
内嵌的Jetty目前不支持JSPs。
Undertow不支持JSPs。
这里有个JSP示例,你可以查看如何设置相关事项。

4.6 安全
如果Spring Security在classpath下,那么web应用默认对所有的HTTP路径(也称为终点,端点,表示API的具体网址)使用’basic’认证。为了给web应用添加方法级别的保护,你可以添加@EnableGlobalMethodSecurity并使用想要的设置。其他信息参考Spring Security Reference。

默认的AuthenticationManager有一个单一的user(’user’的用户名和随机密码会在应用启动时以INFO日志级别打印出来)。如下:

Using default security password: 78fa095d-3f4c-48b1-ad50-e24c31d5cf35
注:如果你对日志配置进行微调,确保org.springframework.boot.autoconfigure.security类别能记录INFO信息,否则默认的密码不会被打印。

你可以通过提供security.user.password改变默认的密码。这些和其他有用的属性通过SecurityProperties(以security为前缀的属性)被外部化了。

默认的安全配置(security configuration)是在SecurityAutoConfiguration和导入的类中实现的(SpringBootWebSecurityConfiguration用于web安全,AuthenticationManagerConfiguration用于与非web应用也相关的认证配置)。你可以添加一个@EnableWebSecurity bean来彻底关掉Spring Boot的默认配置。为了对它进行自定义,你需要使用外部的属性配置和WebSecurityConfigurerAdapter类型的beans(比如,添加基于表单的登陆)。在Spring Boot示例里有一些安全相关的应用可以带你体验常见的用例。

在一个web应用中你能得到的基本特性如下:

一个使用内存存储的AuthenticationManager bean和唯一的user(查看SecurityProperties.User获取user的属性)。
忽略(不保护)常见的静态资源路径(/css/, /js/, /images/和 /favicon.ico)。
对其他的路径实施HTTP Basic安全保护。
安全相关的事件会发布到Spring的ApplicationEventPublisher(成功和失败的认证,拒绝访问)。
Spring Security提供的常见底层特性(HSTS, XSS, CSRF, 缓存)默认都被开启。
上述所有特性都能打开和关闭,或使用外部的配置进行修改(security.*)。为了覆盖访问规则(access rules)而不改变其他自动配置的特性,你可以添加一个使用@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)注解的WebSecurityConfigurerAdapter类型的@Bean。

如果Actuator也在使用,你会发现:

即使应用路径不受保护,被管理的路径也会受到保护。
安全相关的事件被转换为AuditEvents(审计事件),并发布给AuditService。
默认的用户有ADMIN和USER的角色。
使用外部属性能够修改Actuator(执行器)的安全特性(management.security.*)。为了覆盖应用程序的访问规则,你可以添加一个WebSecurityConfigurerAdapter类型的@Bean。同时,如果不想覆盖执行器的访问规则,你可以使用@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)注解该bean,否则使用@Order(ManagementServerProperties.ACCESS_OVERRIDE_ORDER)注解该bean。

4.7 使用sql数据库
Spring框架为使用SQL数据库提供了广泛的支持。从使用JdbcTemplate直接访问JDBC到完全的对象关系映射技术,比如Hibernate。Spring Data提供一个额外的功能,直接从接口创建Repository实现,并使用约定从你的方法名生成查询。

4.7.1 配置DataSource
Java的javax.sql.DataSource接口提供了一个标准的使用数据库连接的方法。传统做法是,一个DataSource使用一个URL连同相应的证书去初始化一个数据库连接。

4.7.1.1 对内嵌数据库的支持
开发应用时使用内存数据库是很实用的。显而易见地,内存数据库不需要提供持久化存储。你不需要在应用启动时填充数据库,也不需要在应用结束时丢弃数据。

Spring Boot可以自动配置的内嵌数据库包括H2, HSQL和Derby。你不需要提供任何连接URLs,只需要简单的添加你想使用的内嵌数据库依赖。

示例:典型的POM依赖如下:


org.springframework.boot
spring-boot-starter-data-jpa


org.hsqldb
hsqldb
runtime

注:对于自动配置的内嵌数据库,你需要依赖spring-jdbc。在示例中,它通过spring-boot-starter-data-jpa被传递地拉过来了。

4.7.1.2 连接到一个生产环境数据库
在生产环境中,数据库连接可以使用DataSource池进行自动配置。下面是选取一个特定实现的算法:

由于Tomcat数据源连接池的性能和并发,在tomcat可用时,我们总是优先使用它。
如果HikariCP可用,我们将使用它。
如果Commons DBCP可用,我们将使用它,但在生产环境不推荐使用它。
最后,如果Commons DBCP2可用,我们将使用它。
如果你使用spring-boot-starter-jdbc或spring-boot-starter-data-jpa ‘starter POMs’,你将会自动获取对tomcat-jdbc的依赖。

注:其他的连接池可以手动配置。如果你定义自己的DataSource bean,自动配置不会发生。

DataSource配置通过外部配置文件的spring.datasource.*属性控制。示例中,你可能会在application.properties中声明下面的片段:

spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
其他可选的配置可以查看DataSourceProperties。同时注意你可以通过spring.datasource.*配置任何DataSource实现相关的特定属性:具体参考你使用的连接池实现的文档。

注:既然Spring Boot能够从大多数数据库的url上推断出driver-class-name,那么你就不需要再指定它了。对于一个将要创建的DataSource连接池,我们需要能够验证Driver是否可用,所以我们会在做任何事情之前检查它。比如,如果你设置spring.datasource.driverClassName=com.mysql.jdbc.Driver,然后这个类就会被加载。

4.7.1.3 连接到一个JNDI数据库
如果正在将Spring Boot应用部署到一个应用服务器,你可能想要用应用服务器内建的特性来配置和管理你的DataSource,并使用JNDI访问它。

spring.datasource.jndi-name属性可以用来替代spring.datasource.url,spring.datasource.username和spring.datasource.password去从一个特定的JNDI路径访问DataSource。比如,下面application.properties中的片段展示了如何获取JBoss定义的DataSource:

spring.datasource.jndi-name=java:jboss/datasources/customers
4.7.2 使用JdbcTemplate
Spring的JdbcTemplate和NamedParameterJdbcTemplate类是被自动配置的,你可以在自己的beans中通过@Autowire直接注入它们。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

private final JdbcTemplate jdbcTemplate;@Autowiredpublic MyBean(JdbcTemplate jdbcTemplate) {    this.jdbcTemplate = jdbcTemplate;}// ...

}
4.7.3 JPA和Spring Data
Java持久化API是一个允许你将对象映射为关系数据库的标准技术。spring-boot-starter-data-jpa POM提供了一种快速上手的方式。它提供下列关键的依赖:

Hibernate - 一个非常流行的JPA实现。
Spring Data JPA - 让实现基于JPA的repositories更容易。
Spring ORMs - Spring框架的核心ORM支持。
注:我们不想在这涉及太多关于JPA或Spring Data的细节。你可以参考来自spring.io的指南使用JPA获取数据,并阅读Spring Data JPA和Hibernate的参考文档。

4.7.3.1 实体类
传统上,JPA实体类被定义到一个persistence.xml文件中。在Spring Boot中,这个文件不是必需的,并被’实体扫描’替代。默认情况下,在你主(main)配置类(被@EnableAutoConfiguration或@SpringBootApplication注解的类)下的所有包都将被查找。

任何被@Entity,@Embeddable或@MappedSuperclass注解的类都将被考虑。一个普通的实体类看起来像下面这样:

package com.example.myapp.domain;

import java.io.Serializable;
import javax.persistence.*;

@Entity
public class City implements Serializable {

@Id
@GeneratedValue
private Long id;

@Column(nullable = false)
private String name;

@Column(nullable = false)
private String state;

// … additional members, often include @OneToMany mappings

protected City() {
// no-args constructor required by JPA spec
// this one is protected since it shouldn’t be used directly
}

public City(String name, String state) {
this.name = name;
this.country = country;
}

public String getName() {
return this.name;
}

public String getState() {
return this.state;
}
// … etc
}
注:你可以使用@EntityScan注解自定义实体扫描路径。具体参考Section 67.4, “Separate @Entity definitions from Spring configuration”。

4.7.3.2 Spring Data JPA仓库
Spring Data JPA仓库(repositories)是用来定义访问数据的接口。根据你的方法名,JPA查询会被自动创建。比如,一个CityRepository接口可能声明一个findAllByState(String state)方法,用来查找给定状态的所有城市。

对于比较复杂的查询,你可以使用Spring Data的Query来注解你的方法。

Spring Data仓库通常继承自Repository或CrudRepository接口。如果你使用自动配置,包括在你的主配置类(被@EnableAutoConfiguration或@SpringBootApplication注解的类)的包下的仓库将会被搜索。

下面是一个传统的Spring Data仓库:

package com.example.myapp.domain;

import org.springframework.data.domain.*;
import org.springframework.data.repository.*;

public interface CityRepository extends Repository

!/bin/bash

cd $OPENSHIFT_REPO_DIR
mvn package -s .openshift/settings.xml -DskipTests=true
3.添加一个调用java -jar …​的start hook

!/bin/bash

cd OPENSHIFTREPODIRnohupjavajartarget/.jarserver.port={OPENSHIFT_DIY_PORT} --server.address=${OPENSHIFT_DIY_IP} &
4.使用一个stop hook

!/bin/bash

source OPENSHIFTCARTRIDGESDKBASHPID=(ps -ef | grep java.*\.jar | grep -v grep | awk '{ print 2 }’)  
if [ -z “
PID” ]
then
client_result “Application is already stopped”
else
kill $PID
fi
5.将内嵌的服务绑定到平台提供的在application.properties定义的环境变量,比如

spring.datasource.url: jdbc:mysql://OPENSHIFTMYSQLDBHOST:{OPENSHIFT_MYSQL_DB_PORT}/OPENSHIFTAPPNAMEspring.datasource.username:{OPENSHIFT_MYSQL_DB_USERNAME}
spring.datasource.password: ${OPENSHIFT_MYSQL_DB_PASSWORD}
在Openshift的网站上有一篇running Gradle in Openshift博客,如果想使用gradle构建运行的应用可以参考它。由于一个Gradle bug,你不能使用高于1.6版本的Gradle。

6.4 Google App Engine
Google App Engine跟Servlet 2.5 API是有联系的,所以在不修改的情况系你是不能部署一个Spring应用的。具体查看本指南的Servlet 2.5章节 Container.md)。

Spring Boot CLI
Spring Boot CLI是一个命令行工具,如果想使用Spring进行快速开发可以使用它。它允许你运行Groovy脚本,这意味着你可以使用熟悉的类Java语法,并且没有那么多的模板代码。你也可以启动一个新的项目或为Spring Boot CLI编写自己的命令。

7.1 安装CLI
你可以手动安装Spring Boot CLI,也可以使用GVM(Groovy环境管理工具)或Homebrew,MacPorts(如果你是一个OSX用户)。参考”Getting started”的Section 10.2, “Installing the Spring Boot CLI” 可以看到全面的安装指令。

7.2 使用CLI
一旦安装好CLI,你可以输入spring来运行它。如果你不使用任何参数运行spring,将会展现一个简单的帮助界面:

$ spring
usage: spring [–help] [–version]
[]

Available commands are:

run [options] [–] [args]
Run a spring groovy script

… more command help is shown here
你可以使用help获取任何支持命令的详细信息。例如:

$ spring help run
spring run - Run a spring groovy script

usage: spring run [options] [–] [args]

Option Description
—— ———–
–autoconfigure [Boolean] Add autoconfigure compiler
transformations (default: true)
–classpath, -cp Additional classpath entries
-e, –edit Open the file with the default system
editor
–no-guess-dependencies Do not attempt to guess dependencies
–no-guess-imports Do not attempt to guess imports
-q, –quiet Quiet logging
-v, –verbose Verbose logging of dependency
resolution
–watch Watch the specified file for changes
version命令提供一个检查你正在使用的Spring Boot版本的快速方式:

$ spring version
Spring CLI v1.3.0.BUILD-SNAPSHOT
7.2.1 使用CLI运行应用
你可以使用run命令编译和运行Groovy源代码。Spring Boot CLI完全自包含,以致于你不需要安装任何外部的Groovy。

下面是一个使用Groovy编写的”hello world” web应用: hello.grooy

@RestController
class WebApplication {

@RequestMapping("/")String home() {    "Hello World!"}

}
想要编译和运行应用,输入:

$ spring run hello.groovy
想要给应用传递命令行参数,你需要使用一个–来将它们和”spring”命令参数区分开来。例如:

$ spring run hello.groovy – –server.port=9000
想要设置JVM命令行参数,你可以使用JAVA_OPTS环境变量,例如:

$ JAVA_OPTS=-Xmx1024m spring run hello.groovy
7.2.1.1 推断”grab”依赖
标准的Groovy包含一个@Grab注解,它允许你声明对第三方库的依赖。这项有用的技术允许Groovy以和Maven或Gradle相同的方式下载jars,但不需要使用构建工具。

Spring Boot进一步延伸了该技术,它会基于你的代码尝试推导你”grab”哪个库。例如,由于WebApplication代码上使用了@RestController注解,”Tomcat”和”Spring MVC”将被获取(grabbed)。

下面items被用作”grab hints”:

items Grabs
JdbcTemplate,NamedParameterJdbcTemplate,DataSource JDBC应用
@EnableJms JMS应用
@EnableCaching Caching abstraction
@Test JUnit
@EnableRabbit RabbitMQ
@EnableReactor Project Reactor
继承Specification Spock test
@EnableBatchProcessing Spring Batch
@MessageEndpoint,@EnableIntegrationPatterns Spring Integration
@EnableDeviceResolver Spring Mobile
@Controller,@RestController,@EnableWebMvc Spring MVC + Embedded Tomcat
@EnableWebSecurity Spring Security
@EnableTransactionManagement Spring Transaction Management
注:想要理解自定义是如何生效,可以查看Spring Boot CLI源码中的CompilerAutoConfiguration子类。

7.2.1.2 推断”grab”坐标
Spring Boot扩展Groovy标准”@Grab”注解使其能够允许你指定一个没有group或version的依赖,例如@Grab(‘freemarker’)。 artifact’s的组和版本是通过查看Spring Boot的依赖元数据推断出来的。注意默认的元数据是和你使用的CLI版本绑定的-只有在你迁移到一个CLI新版本时它才会改变,这样当你的依赖改变时你就可以控制了。在附录的表格中可以查看默认元数据包含的依赖和它们的版本。

7.2.1.3 默认import语句
为了帮助你减少Groovy代码量,一些import语句被自动包含进来了。注意上面的示例中引用@Component,@RestController和@RequestMapping而没有使用全限定名或import语句。

注:很多Spring注解在不使用import语句的情况下可以正常工作。尝试运行你的应用,看一下在添加imports之前哪些会失败。

7.2.1.4 自动创建main方法
跟等效的Java应用不同,你不需要在Groovy脚本中添加一个public static void main(String[] args)方法。Spring Boot 会使用你编译后的代码自动创建一个SpringApplication。

7.2.1.5 自定义”grab”元数据
Spring Boot提供一个新的@GrabMetadata注解,你可以使用它提供自定义的依赖元数据,以覆盖Spring Boot的默认配置。该元数据通过使用提供一个或多个配置文件坐标的注解来指定(使用一个属性标识符”type”部署到Maven仓库).。配置文件中的每个实体必须遵循group:module=version的格式。

例如,下面的声明:

@GrabMetadata("com.example.custom-versions:1.0.0")
将会加载Maven仓库处于com/example/custom-versions/1.0.0/下的custom-versions-1.0.0.properties文件。

可以通过注解指定多个属性文件,它们会以声明的顺序被使用。例如:

@GrabMetadata(["com.example.custom-versions:1.0.0",
"com.example.more-versions:1.0.0"])

意味着位于more-versions的属性将覆盖位于custom-versions的属性。

你可以在任何能够使用@Grab的地方使用@GrabMetadata,然而,为了确保元数据的顺序一致,你在应用程序中最多只能使用一次@GrabMetadata。Spring IO Platform是一个非常有用的依赖元数据源(Spring Boot的超集),例如:

@GrabMetadata(‘io.spring.platform:platform-versions:1.0.4.RELEASE’)
7.2.2 测试你的代码
test命令允许你编译和运行应用程序的测试用例。常规使用方式如下:

$ spring test app.groovy tests.groovy
Total: 1, Success: 1, : Failures: 0
Passed? true
在这个示例中,test.groovy包含JUnit @Test方法或Spock Specification类。所有的普通框架注解和静态方法在不使用import导入的情况下,仍旧可以使用。

下面是我们使用的test.groovy文件(含有一个JUnit测试):

class ApplicationTests {

@Testvoid homeSaysHello() {    assertEquals("Hello World!", new WebApplication().home())}

}
注:如果有多个测试源文件,你可以倾向于使用一个test目录来组织它们。

7.2.3 多源文件应用
你可以在所有接收文件输入的命令中使用shell通配符。这允许你轻松处理来自一个目录下的多个文件,例如:

$ spring run *.groovy
如果你想将’test’或’spec’代码从主应用代码中分离,这项技术就十分有用了:

$ spring test app/.groovy test/.groovy
7.2.4 应用打包
你可以使用jar命令打包应用程序为一个可执行的jar文件。例如:

$ spring jar my-app.jar *.groovy
最终的jar包括编译应用产生的类和所有依赖,这样你就可以使用java -jar来执行它了。该jar文件也包括来自应用classpath的实体。你可以使用–include和–exclude添加明确的路径(两者都是用逗号分割,同样都接收值为’+’和’-‘的前缀,’-‘意味着它们将从默认设置中移除)。默认包含(includes):

public/, resources/, static/, templates/, META-INF/*,
默认排除(excludes):

., repository/, build/, target/, /.jar, */.groovy
查看spring help jar可以获得更多信息。

7.2.5 初始化新工程
init命令允许你使用start.spring.io在不离开shell的情况下创建一个新的项目。例如:

$ spring init –dependencies=web,data-jpa my-project
Using service at https://start.spring.io
Project extracted to ‘/Users/developer/example/my-project’
这创建了一个my-project目录,它是一个基本Maven且依赖spring-boot-starter-web和spring-boot-starter-data-jpa的项目。你可以使用–list参数列出该服务的能力。

$ spring init –list

Capabilities of https://start.spring.io

Available dependencies:

actuator - Actuator: Production ready features to help you monitor and manage your application

web - Web: Support for full-stack web development, including Tomcat and spring-webmvc
websocket - Websocket: Support for WebSocket development
ws - WS: Support for Spring Web Services

Available project types:

gradle-build - Gradle Config [format:build, build:gradle]
gradle-project - Gradle Project [format:project, build:gradle]
maven-build - Maven POM [format:build, build:maven]
maven-project - Maven Project [format:project, build:maven] (default)


init命令支持很多选项,查看help输出可以获得更多详情。例如,下面的命令创建一个使用Java8和war打包的gradle项目:

$ spring init –build=gradle –java-version=1.8 –dependencies=websocket –packaging=war sample-app.zip
Using service at https://start.spring.io
Content saved to ‘sample-app.zip’
7.2.6 使用内嵌shell
Spring Boot包括完整的BASH和zsh shells的命令行脚本。如果你不使用它们中的任何一个(可能你是一个Window用户),那你可以使用shell命令启用一个集成shell。

$ spring shell
Spring Boot (v1.3.0.BUILD-SNAPSHOT)
Hit TAB to complete. Type \’help’ and hit RETURN for help, and \’exit’ to quit.
从内嵌shell中可以直接运行其他命令:

versionSpringCLIv1.3.0.BUILDSNAPSHOTshellANSItab使前缀。点击ctrl-c将退出内嵌shell。

7.2.7 为CLI添加扩展
使用install命令可以为CLI添加扩展。该命令接收一个或多个格式为group:artifact:version的artifact坐标集。例如:

$ spring install com.example:spring-boot-cli-extension:1.0.0.RELEASE
除了安装你提供坐标的artifacts标识外,所有依赖也会被安装。使用uninstall可以卸载一个依赖。和install命令一样,它接收一个或多个格式为group:artifact:version的artifact坐标集。例如:

$ spring uninstall com.example:spring-boot-cli-extension:1.0.0.RELEASE
它会通过你提供的坐标卸载相应的artifacts标识和它们的依赖。

为了卸载所有附加依赖,你可以使用–all选项。例如:

$ spring uninstall –all
7.3 使用Groovy beans DSL开发应用
Spring框架4.0版本对beans{} DSL(借鉴自Grails)提供原生支持,你可以使用相同的格式在你的Groovy应用程序脚本中嵌入bean定义。有时候这是一个包括外部特性的很好的方式,比如中间件声明。例如:

@Configuration
class Application implements CommandLineRunner {

@AutowiredSharedService service@Overridevoid run(String... args) {    println service.message}

}

import my.company.SharedService

beans {
service(SharedService) {
message = “Hello World”
}
}
你可以使用beans{}混合位于相同文件的类声明,只要它们都处于顶级,或如果你喜欢的话,可以将beans DSL放到一个单独的文件中。

构建工具插件
Spring Boot为Maven和Gradle提供构建工具插件。该插件提供各种各样的特性,包括打包可执行jars。本节提供关于插件的更多详情及用于扩展一个不支持的构建系统所需的帮助信息。如果你是刚刚开始,那可能需要先阅读Part III, “Using Spring Boot”章节的“Chapter 13, Build systems”。

8.1 Spring Boot Maven插件
Spring Boot Maven插件为Maven提供Spring Boot支持,它允许你打包可执行jar或war存档,然后就地运行应用。为了使用它,你需要使用Maven 3.2 (或更高版本)。

注:参考Spring Boot Maven Plugin Site可以获取全部的插件文档。

8.1.1 包含该插件
想要使用Spring Boot Maven插件只需简单地在你的pom.xml的plugins部分包含相应的XML:

port: 9000

spring:
profiles: development
server:
port: 9001


spring:
profiles: production
server:
port: 0
在这个示例中,默认的端口是9000,但如果Spring profile ‘development’生效则该端口是9001,如果’production’生效则它是0。

YAML文档以它们遇到的顺序合并(所以后面的值会覆盖前面的值)。

想要使用profiles文件完成同样的操作,你可以使用application-${profile}.properties指定特殊的,profile相关的值。

9.2.7 发现外部属性的内置选项
Spring Boot在运行时将来自application.properties(或.yml)的外部属性绑定进一个应用中。在一个地方不可能存在详尽的所有支持属性的列表(技术上也是不可能的),因为你的classpath下的其他jar文件也能够贡献。

每个运行中且有Actuator特性的应用都会有一个configprops端点,它能够展示所有边界和可通过@ConfigurationProperties绑定的属性。

附录中包含一个application.properties示例,它列举了Spring Boot支持的大多数常用属性。获取权威列表可搜索@ConfigurationProperties和@Value的源码,还有不经常使用的RelaxedEnvironment。

9.3 内嵌的servlet容器
9.3.1 为应用添加Servlet,Filter或ServletContextListener
Servlet规范支持的Servlet,Filter,ServletContextListener和其他监听器可以作为@Bean定义添加到你的应用中。需要格外小心的是,它们不会引起太多的其他beans的热初始化,因为在应用生命周期的早期它们已经被安装到容器里了(比如,让它们依赖你的DataSource或JPA配置就不是一个好主意)。你可以通过延迟初始化它们到第一次使用而不是初始化时来突破该限制。

在Filters和Servlets的情况下,你也可以通过添加一个FilterRegistrationBean或ServletRegistrationBean代替或以及底层的组件来添加映射(mappings)和初始化参数。

9.3.2 改变HTTP端口
在一个单独的应用中,主HTTP端口默认为8080,但可以使用server.port设置(比如,在application.properties中或作为一个系统属性)。由于Environment值的宽松绑定,你也可以使用SERVER_PORT(比如,作为一个OS环境变)。

为了完全关闭HTTP端点,但仍创建一个WebApplicationContext,你可以设置server.port=-1(测试时可能有用)。

想获取更多详情可查看’Spring Boot特性’章节的Section 26.3.3, “Customizing embedded servlet containers”,或ServerProperties源码。

9.3.3 使用随机未分配的HTTP端口
想扫描一个未使用的端口(为了防止冲突使用OS本地端口)可以使用server.port=0。

9.3.4 发现运行时的HTTP端口
你可以通过日志输出或它的EmbeddedServletContainer的EmbeddedWebApplicationContext获取服务器正在运行的端口。获取和确认服务器已经初始化的最好方式是添加一个ApplicationListener类型的@Bean,然后当事件发布时将容器pull出来。

使用@WebIntegrationTests的一个有用实践是设置server.port=0,然后使用@Value注入实际的(’local’)端口。例如:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SampleDataJpaApplication.class)
@WebIntegrationTest(“server.port:0”)
public class CityRepositoryIntegrationTests {

@AutowiredEmbeddedWebApplicationContext server;@Value("${local.server.port}")int port;// ...

}
9.3.5 配置SSL
SSL能够以声明方式进行配置,一般通过在application.properties或application.yml设置各种各样的server.ssl.*属性。例如:

server.port = 8443
server.ssl.key-store = classpath:keystore.jks
server.ssl.key-store-password = secret
server.ssl.key-password = another-secret
获取所有支持的配置详情可查看Ssl。

注:Tomcat要求key存储(如果你正在使用一个可信存储)能够直接在文件系统上访问,即它不能从一个jar文件内读取。Jetty和Undertow没有该限制。

使用类似于以上示例的配置意味着该应用将不在支持端口为8080的普通HTTP连接。Spring Boot不支持通过application.properties同时配置HTTP连接器和HTTPS连接器。如果你两个都想要,那就需要以编程的方式配置它们中的一个。推荐使用application.properties配置HTTPS,因为HTTP连接器是两个中最容易以编程方式进行配置的。获取示例可查看spring-boot-sample-tomcat-multi-connectors示例项目。

9.3.6 配置Tomcat
通常你可以遵循Section 63.7, “Discover built-in options for external properties”关于@ConfigurationProperties(这里主要的是ServerProperties)的建议,但也看下EmbeddedServletContainerCustomizer和各种你可以添加的Tomcat-specific的*Customizers。

Tomcat APIs相当丰富,一旦获取到TomcatEmbeddedServletContainerFactory,你就能够以多种方式修改它。或核心选择是添加你自己的TomcatEmbeddedServletContainerFactory。

9.3.7 启用Tomcat的多连接器(Multiple Connectors)
你可以将一个org.apache.catalina.connector.Connector添加到TomcatEmbeddedServletContainerFactory,这就能够允许多连接器,比如HTTP和HTTPS连接器:

@Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
tomcat.addAdditionalTomcatConnectors(createSslConnector());
return tomcat;
}

private Connector createSslConnector() {
Connector connector = new Connector(“org.apache.coyote.http11.Http11NioProtocol”);
Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
try {
File keystore = new ClassPathResource(“keystore”).getFile();
File truststore = new ClassPathResource(“keystore”).getFile();
connector.setScheme(“https”);
connector.setSecure(true);
connector.setPort(8443);
protocol.setSSLEnabled(true);
protocol.setKeystoreFile(keystore.getAbsolutePath());
protocol.setKeystorePass(“changeit”);
protocol.setTruststoreFile(truststore.getAbsolutePath());
protocol.setTruststorePass(“changeit”);
protocol.setKeyAlias(“apitester”);
return connector;
}
catch (IOException ex) {
throw new IllegalStateException(“can’t access keystore: [” + “keystore”
+ “] or truststore: [” + “keystore” + “]”, ex);
}
}
9.3.8 在前端代理服务器后使用Tomcat
Spring Boot将自动配置Tomcat的RemoteIpValve,如果你启用它的话。这允许你透明地使用标准的x-forwarded-for和x-forwarded-proto头,很多前端代理服务器都会添加这些头信息(headers)。通过将这些属性中的一个或全部设置为非空的内容来开启该功能(它们是大多数代理约定的值,如果你只设置其中的一个,则另一个也会被自动设置)。

server.tomcat.remote_ip_header=x-forwarded-for
server.tomcat.protocol_header=x-forwarded-proto
如果你的代理使用不同的头部(headers),你可以通过向application.properties添加一些条目来自定义该值的配置,比如:

server.tomcat.remote_ip_header=x-your-remote-ip-header
server.tomcat.protocol_header=x-your-protocol-header
该值也可以配置为一个默认的,能够匹配信任的内部代理的正则表达式。默认情况下,受信任的IP包括 10/8, 192.168/16, 169.254/16 和 127/8。可以通过向application.properties添加一个条目来自定义该值的配置,比如:

server.tomcat.internal_proxies=192\.168\.\d{1,3}\.\d{1,3}
注:只有在你使用一个properties文件作为配置的时候才需要双反斜杠。如果你使用YAML,单个反斜杠就足够了,192.168.\d{1,3}.\d{1,3}和上面的等价。

另外,通过在一个TomcatEmbeddedServletContainerFactory bean中配置和添加RemoteIpValve,你就可以完全控制它的设置了。

9.3.9 使用Jetty替代Tomcat
Spring Boot starters(特别是spring-boot-starter-web)默认都是使用Tomcat作为内嵌容器的。你需要排除那些Tomcat的依赖并包含Jetty的依赖。为了让这种处理尽可能简单,Spring Boot将Tomcat和Jetty的依赖捆绑在一起,然后提供单独的starters。

Maven示例:


org.springframework.boot
spring-boot-starter-web


org.springframework.boot
spring-boot-starter-tomcat




org.springframework.boot
spring-boot-starter-jetty

Gradle示例:

configurations {
compile.exclude module: “spring-boot-starter-tomcat”
}

dependencies {
compile(“org.springframework.boot:spring-boot-starter-web:1.3.0.BUILD-SNAPSHOT”)
compile(“org.springframework.boot:spring-boot-starter-jetty:1.3.0.BUILD-SNAPSHOT”)
// …
}
9.3.10 配置jetty
通常你可以遵循Section 63.7, “Discover built-in options for external properties”关于@ConfigurationProperties(此处主要是ServerProperties)的建议,但也要看下EmbeddedServletContainerCustomizer。Jetty API相当丰富,一旦获取到JettyEmbeddedServletContainerFactory,你就可以使用很多方式修改它。或更彻底地就是添加你自己的JettyEmbeddedServletContainerFactory。

9.3.11 使用Undertow替代Tomcat
使用Undertow替代Tomcat和使用Jetty替代Tomcat非常类似。你需要排除Tomat依赖,并包含Undertow starter。

Maven示例:


org.springframework.boot
spring-boot-starter-web


org.springframework.boot
spring-boot-starter-tomcat




org.springframework.boot
spring-boot-starter-undertow

Gradle示例:

configurations {
compile.exclude module: “spring-boot-starter-tomcat”
}

dependencies {
compile ‘org.springframework.boot:spring-boot-starter-web:1.3.0.BUILD-SNAPSHOT”)
compile ‘org.springframework.boot:spring-boot-starter-undertow:1.3.0.BUILD-SNAPSHOT”)
// …
}
9.3.12 配置Undertow
通常你可以遵循Section 63.7, “Discover built-in options for external properties”关于@ConfigurationProperties(此处主要是ServerProperties和ServerProperties.Undertow),但也要看下EmbeddedServletContainerCustomizer。一旦获取到UndertowEmbeddedServletContainerFactory,你就可以使用一个UndertowBuilderCustomizer修改Undertow的配置以满足你的需求。或更彻底地就是添加你自己的UndertowEmbeddedServletContainerFactory。

9.3.13 启用Undertow的多监听器(Multiple Listeners)
往UndertowEmbeddedServletContainerFactory添加一个UndertowBuilderCustomizer,然后添加一个监听者到Builder:

@Bean
public UndertowEmbeddedServletContainerFactory embeddedServletContainerFactory() {
UndertowEmbeddedServletContainerFactory factory = new UndertowEmbeddedServletContainerFactory();
factory.addBuilderCustomizers(new UndertowBuilderCustomizer() {

    @Override    public void customize(Builder builder) {        builder.addHttpListener(8080, "0.0.0.0");    }});return factory;

}
9.3.14 使用Tomcat7
Tomcat7可用于Spring Boot,但默认使用的是Tomcat8。如果不能使用Tomcat8(例如,你使用的是Java1.6),你需要改变classpath去引用Tomcat7。

9.3.14.1 通过Maven使用Tomcat7
如果正在使用starter pom和parent,你只需要改变Tomcat的version属性,比如,对于一个简单的webapp或service:


0 0