Spring Boot 参考指南(翻译中)

作者

Phillip Webb, Dave Syer, Josh Long, Stéphane Nicoll, Rob Winch, Andy Wilkinson, Marcel Overdijk, Christian Dupuis, Sébastien Deleuze, Michael Simons

翻译说明:非常抱歉,由于时间原因和原文档页面排版比较杂,本人难以翻译和校对,因此,暂停翻译一段时间,等正在翻译中的 NGINX 中文文档完成,就把当前的 Spring Boot 文档做成 Markdown 版本,托管至 Github,翻译会继续,但不是这个 1.5.4 版本,可能是最新的发行版本。敬请期待!

1.5.4.RELEASE

只要您不对文档副本收取任何费用,并且无论是以印刷版还是电子版分发,每个副本都包含本版权声明,本文档的副本可供您自己使用并分发给他人。


目录

I. Spring Boot文档
1. 关于文档
2. 获取帮助
3. 起步
4. 使用Spring Boot
5. 了解Spring Boot特性
6. 转移到生产环境
7. 高级主题
II. 入门
8. Spring Boot简介
9. 系统要求
9.1. Servlet容器
10. 安装Spring Boot
10.1. 对Java开发人员的安装说明
10.1.1. Maven安装
10.1.2. Gradle安装
10.2. 安装Spring Boot CLI
10.2.1. 手动安装
10.2.2. 使用SDKMAN!安装
10.2.3. OSX Homebrew安装
10.2.4. MacPorts安装
10.2.5. 命令行完成
10.2.6. 快速开始Spring CLI示例
10.3. 升级早期版本的Spring Boot
11. 开发您的第一个Spring Boot应用
11.1. 创建POM
11.2. 添加classpath依赖
11.3. 编码
11.3.1. @RestController和@RequestMapping注解
11.3.2. @EnableAutoConfiguration注解
11.3.3. “main”方法
11.4. 运行示例
11.5. 创建可执行jar
12. 接下来要看什么
III. 使用Spring Boot
13. 构建系统
13.1. 依赖管理
13.2. Maven
13.2.1. 继承starter parent
13.2.2. 使用没有父POM的Spring
13.2.3. 变更Java版本
13.2.4. 使用Spring Boot Maven插件
13.3. Gradle
13.4. Ant
13.5. Starter
14. 结构化您的代码
14.1. 使用“default”包
14.2. 定位主应用类
15. 配置类
15.1. 导入其它配置类
15.2. 导入XML配置
16. 自动配置
16.1. 逐渐替代自动配置
16.2. 禁用指定的自动配置
17. Spring Bean与依赖注入
18. 使用@SpringBootApplication注解
19. 运行您的应用
19.1. 使用IDE运行
19.2. 作为打包应用运行
19.3. 使用Maven插件
19.4. 使用Gradle插件
19.5. 热拔插
20. 开发者工具
20.1. Property默认值
20.2. 自动重启
20.2.1. 排除资源
20.2.2. 监视附加路径
20.2.3. 禁止重启
20.2.4. 使用触发文件
20.2.5. 自定义重启类加载器
20.2.6. 已知限制
20.3. LiveReload
20.4. 全局设置
20.5. 远程应用
20.5.1. 运行远程客户端应用
20.5.2. 远程更新
20.5.3. 远程调试隧道
21. 打包应用用于生产
22. 接下来看什么
IV. Spring Boot功能
23. SpringApplication
23.1. 启动失败
23.2. 自定义Banner
23.3. 定制 SpringApplication
23.4. 链式构建器 API
23.5. 应用程序事件与监听器
23.6. Web环境
23.7. 访问应用程序参数
23.8. 使用 ApplicationRunner 或者 CommandLineRunner
23.9. 退出应用程序
23.10. 管理功能
24. 外部配置
24.1. 配置随机值
24.2. Accessing command line properties
24.3. Application property files
24.4. Profile-specific properties
24.5. Placeholders in properties
24.6. Using YAML instead of Properties
24.6.1. Loading YAML
24.6.2. Exposing YAML as properties in the Spring Environment
24.6.3. Multi-profile YAML documents
24.6.4. YAML shortcomings
24.6.5. Merging YAML lists
24.7. Type-safe Configuration Properties
24.7.1. Third-party configuration
24.7.2. Relaxed binding
24.7.3. Properties conversion
24.7.4. @ConfigurationProperties Validation
24.7.5. @ConfigurationProperties vs. @Value
25. Profiles
25.1. Adding active profiles
25.2. Programmatically setting profiles
25.3. Profile-specific configuration files
26. Logging
26.1. Log format
26.2. Console output
26.2.1. Color-coded output
26.3. File output
26.4. Log Levels
26.5. Custom log configuration
26.6. Logback extensions
26.6.1. Profile-specific configuration
26.6.2. Environment properties
27. 开发 web 应用程序
27.1. Spring Web MVC 框架
27.1.1. Spring MVC 自动配置
27.1.2. HttpMessageConverter
27.1.3. 定制 JSON Serializers 与 Deserializers
27.1.4. MessageCodesResolver
27.1.5. 静态内容
27.1.6. 定制 Favicon
27.1.7. ConfigurableWebBindingInitializer
27.1.8. 模板引擎
27.1.9. 错误处理
定制错误页面
映射 Spring MVC 之外的错误页面
WebSphere Application Server 上的错误处理
27.1.10. Spring HATEOAS
27.1.11. CORS 支持
27.2. JAX-RS 与 Jersey
27.3. 嵌入式 servlet 容器支持
27.3.1. Servlet、 Filter 与监听器
将 Servlet、Filter 和监听器注册为 Spring bean
27.3.2. Servlet 上下文初始化
扫描 Servlet、Filter 和监听器
27.3.3. EmbeddedWebApplicationContext
27.3.4. 定制嵌入式 servlet 容器
编程形式定制
直接定制 ConfigurableEmbeddedServletContainer
27.3.5. JSP 限制
28. Security
28.1. OAuth2
28.1.1. Authorization Server
28.1.2. Resource Server
28.2. Token Type in User Info
28.3. Customizing the User Info RestTemplate
28.3.1. Client
28.3.2. Single Sign On
28.4. Actuator Security
29. 使用 SQL 数据库
29.1. 配置数据源
29.1.1. 嵌入式数据库支持
29.1.2. 连接到生产数据库
29.1.3. 连接到 JNDI 数据源
29.2. 使用 JdbcTemplate
29.3. JPA 与 Spring Data
29.3.1. 实体类
29.3.2. Spring Data JPA 资源库
29.3.3. 创建和删除 JPA 数据库
29.3.4. 在 View 中打开 EntityManager
29.4. 使用 H2 的 web 控制台
29.4.1. 更改 H2 控制台的路径
29.4.2. 保护 H2 控制台
29.5. 使用 jOOQ
29.5.1. 代码生成
29.5.2. 使用 DSLContext
29.5.3. 定制 jOOQ
30. 使用 NoSQL 技术
30.1. Redis
30.1.1. 连接到 Redis
30.2. MongoDB
30.2.1. 连接到 MongoDB 数据库
30.2.2. MongoTemplate
30.2.3. Spring Data MongoDB 仓储
30.2.4. 嵌入式 Mongo
30.3. Neo4j
30.3.1. 连接 Neo4j 数据库
30.3.2. 使用内嵌模式
30.3.3. Neo4jSession
30.3.4. Spring Data Neo4j 仓储
30.3.5. 仓储示例
30.4. Gemfire
30.5. Solr
30.5.1. 连接 Solr
30.5.2. Spring Data Solr 仓储
30.6. Elasticsearch
30.6.1. 使用 Jest 连接 Elasticsearch
30.6.2. 使用 Spring Data 连接 Elasticsearch
30.6.3. Spring Data Elasticsearch 仓储
30.7. Cassandra
30.7.1. 连接 Cassandra
30.7.2. Spring Data Cassandra 仓储
30.8. Couchbase
30.8.1. 连接 Couchbase
30.8.2. Spring Data Couchbase 仓储
30.9. LDAP
30.9.1. 连接 LDAP 服务器
30.9.2. Spring Data LDAP 仓储
30.9.3. 嵌入式 LDAP 内存服务器
31. Caching
31.1. Supported cache providers
31.1.1. Generic
31.1.2. JCache (JSR-107)
31.1.3. EhCache 2.x
31.1.4. Hazelcast
31.1.5. Infinispan
31.1.6. Couchbase
31.1.7. Redis
31.1.8. Caffeine
31.1.9. Guava (deprecated)
31.1.10. Simple
31.1.11. None
32. Messaging
32.1. JMS
32.1.1. ActiveMQ support
32.1.2. Artemis support
32.1.3. Using a JNDI ConnectionFactory
32.1.4. Sending a message
32.1.5. Receiving a message
32.2. AMQP
32.2.1. RabbitMQ support
32.2.2. Sending a message
32.2.3. Receiving a message
32.3. Apache Kafka Support
32.3.1. Sending a Message
32.3.2. Receiving a Message
32.3.3. Additional Kafka Properties
33. Calling REST services
33.1. RestTemplate customization
34. Validation
35. Sending email
36. Distributed Transactions with JTA
36.1. Using an Atomikos transaction manager
36.2. Using a Bitronix transaction manager
36.3. Using a Narayana transaction manager
36.4. Using a Java EE managed transaction manager
36.5. Mixing XA and non-XA JMS connections
36.6. Supporting an alternative embedded transaction manager
37. Hazelcast
38. Spring Integration
39. Spring Session
40. Monitoring and management over JMX
41. Testing
41.1. Test scope dependencies
41.2. Testing Spring applications
41.3. Testing Spring Boot applications
41.3.1. Detecting test configuration
41.3.2. Excluding test configuration
41.3.3. Working with random ports
41.3.4. Mocking and spying beans
41.3.5. Auto-configured tests
41.3.6. Auto-configured JSON tests
41.3.7. Auto-configured Spring MVC tests
41.3.8. Auto-configured Data JPA tests
41.3.9. Auto-configured JDBC tests
41.3.10. Auto-configured Data MongoDB tests
41.3.11. Auto-configured REST clients
41.3.12. Auto-configured Spring REST Docs tests
41.3.13. Using Spock to test Spring Boot applications
41.4. Test utilities
41.4.1. ConfigFileApplicationContextInitializer
41.4.2. EnvironmentTestUtils
41.4.3. OutputCapture
41.4.4. TestRestTemplate
42. WebSockets
43. Web Services
44. Creating your own auto-configuration
44.1. Understanding auto-configured beans
44.2. Locating auto-configuration candidates
44.3. Condition annotations
44.3.1. Class conditions
44.3.2. Bean conditions
44.3.3. Property conditions
44.3.4. Resource conditions
44.3.5. Web application conditions
44.3.6. SpEL expression conditions
44.4. Creating your own starter
44.4.1. Naming
44.4.2. Autoconfigure module
44.4.3. Starter module
45. What to read next
V. Spring Boot Actuator: Production-ready features
46. Enabling production-ready features
47. Endpoints
47.1. Customizing endpoints
47.2. Hypermedia for actuator MVC endpoints
47.3. CORS support
47.4. Adding custom endpoints
47.5. Health information
47.6. Security with HealthIndicators
47.6.1. Auto-configured HealthIndicators
47.6.2. Writing custom HealthIndicators
47.7. Application information
47.7.1. Auto-configured InfoContributors
47.7.2. Custom application info information
47.7.3. Git commit information
47.7.4. Build information
47.7.5. Writing custom InfoContributors
48. Monitoring and management over HTTP
48.1. Accessing sensitive endpoints
48.2. Customizing the management endpoint paths
48.3. Customizing the management server port
48.4. Configuring management-specific SSL
48.5. Customizing the management server address
48.6. Disabling HTTP endpoints
48.7. HTTP health endpoint format and access restrictions
49. Monitoring and management over JMX
49.1. Customizing MBean names
49.2. Disabling JMX endpoints
49.3. Using Jolokia for JMX over HTTP
49.3.1. Customizing Jolokia
49.3.2. Disabling Jolokia
50. Monitoring and management using a remote shell (deprecated)
50.1. Connecting to the remote shell
50.1.1. Remote shell credentials
50.2. Extending the remote shell
50.2.1. Remote shell commands
50.2.2. Remote shell plugins
51. Loggers
51.1. Configure a Logger
52. Metrics
52.1. System metrics
52.2. DataSource metrics
52.3. Cache metrics
52.4. Tomcat session metrics
52.5. Recording your own metrics
52.6. Adding your own public metrics
52.7. Special features with Java 8
52.8. Metric writers, exporters and aggregation
52.8.1. Example: Export to Redis
52.8.2. Example: Export to Open TSDB
52.8.3. Example: Export to Statsd
52.8.4. Example: Export to JMX
52.9. Aggregating metrics from multiple sources
52.10. Dropwizard Metrics
52.11. Message channel integration
53. Auditing
54. Tracing
54.1. Custom tracing
55. Process monitoring
55.1. Extend configuration
55.2. Programmatically
56. Cloud Foundry support
56.1. Disabling extended Cloud Foundry actuator support
56.2. Cloud Foundry self signed certificates
56.3. Custom security configuration
57. What to read next
VI. Deploying Spring Boot applications
58. Deploying to the cloud
58.1. Cloud Foundry
58.1.1. Binding to services
58.2. Heroku
58.3. OpenShift
58.4. Amazon Web Services (AWS)
58.4.1. AWS Elastic Beanstalk
Using the Tomcat platform
Using the Java SE platform
Best practices
58.4.2. Summary
58.5. Boxfuse and Amazon Web Services
58.6. Google App Engine
59. Installing Spring Boot applications
59.1. Supported operating systems
59.2. Unix/Linux services
59.2.1. Installation as an init.d service (System V)
Securing an init.d service
59.2.2. Installation as a systemd service
59.2.3. Customizing the startup script
Customizing script when it�s written
Customizing script when it runs
59.3. Microsoft Windows services
60. What to read next
VII. Spring Boot CLI
61. Installing the CLI
62. Using the CLI
62.1. Running applications using the CLI
62.1.1. Deduced �grab� dependencies
62.1.2. Deduced �grab� coordinates
62.1.3. Default import statements
62.1.4. Automatic main method
62.1.5. Custom dependency management
62.2. Testing your code
62.3. Applications with multiple source files
62.4. Packaging your application
62.5. Initialize a new project
62.6. Using the embedded shell
62.7. Adding extensions to the CLI
63. Developing application with the Groovy beans DSL
64. Configuring the CLI with settings.xml
65. What to read next
VIII. Build tool plugins
66. Spring Boot Maven plugin
66.1. Including the plugin
66.2. Packaging executable jar and war files
67. Spring Boot Gradle plugin
67.1. Including the plugin
67.2. Gradle dependency management
67.3. Packaging executable jar and war files
67.4. Running a project in-place
67.5. Spring Boot plugin configuration
67.6. Repackage configuration
67.7. Repackage with custom Gradle configuration
67.7.1. Configuration options
67.7.2. Available layouts
67.7.3. Using a custom layout
67.8. Understanding how the Gradle plugin works
67.9. Publishing artifacts to a Maven repository using Gradle
67.9.1. Configuring Gradle to produce a pom that inherits dependency management
67.9.2. Configuring Gradle to produce a pom that imports dependency management
68. Spring Boot AntLib module
68.1. Spring Boot Ant tasks
68.1.1. spring-boot:exejar
68.1.2. Examples
68.2. spring-boot:findmainclass
68.2.1. Examples
69. Supporting other build systems
69.1. Repackaging archives
69.2. Nested libraries
69.3. Finding a main class
69.4. Example repackage implementation
70. What to read next
IX. �How-to� guides
71. Spring Boot application
71.1. Create your own FailureAnalyzer
71.2. Troubleshoot auto-configuration
71.3. Customize the Environment or ApplicationContext before it starts
71.4. Build an ApplicationContext hierarchy (adding a parent or root context)
71.5. Create a non-web application
72. Properties & configuration
72.1. Automatically expand properties at build time
72.1.1. Automatic property expansion using Maven
72.1.2. Automatic property expansion using Gradle
72.2. Externalize the configuration of SpringApplication
72.3. Change the location of external properties of an application
72.4. Use �short� command line arguments
72.5. Use YAML for external properties
72.6. Set the active Spring profiles
72.7. Change configuration depending on the environment
72.8. Discover built-in options for external properties
73. Embedded servlet containers
73.1. Add a Servlet, Filter or Listener to an application
73.1.1. Add a Servlet, Filter or Listener using a Spring bean
Disable registration of a Servlet or Filter
73.1.2. Add Servlets, Filters, and Listeners using classpath scanning
73.2. Change the HTTP port
73.3. Use a random unassigned HTTP port
73.4. Discover the HTTP port at runtime
73.5. Configure SSL
73.6. Configure Access Logging
73.7. Use behind a front-end proxy server
73.7.1. Customize Tomcat�s proxy configuration
73.8. Configure Tomcat
73.9. Enable Multiple Connectors with Tomcat
73.10. Use Tomcat�s LegacyCookieProcessor
73.11. Use Jetty instead of Tomcat
73.12. Configure Jetty
73.13. Use Undertow instead of Tomcat
73.14. Configure Undertow
73.15. Enable Multiple Listeners with Undertow
73.16. Use Tomcat 7.x or 8.0
73.16.1. Use Tomcat 7.x or 8.0 with Maven
73.16.2. Use Tomcat 7.x or 8.0 with Gradle
73.17. Use Jetty 9.2
73.17.1. Use Jetty 9.2 with Maven
73.17.2. Use Jetty 9.2 with Gradle
73.18. Use Jetty 8
73.18.1. Use Jetty 8 with Maven
73.18.2. Use Jetty 8 with Gradle
73.19. Create WebSocket endpoints using @ServerEndpoint
73.20. Enable HTTP response compression
74. Spring MVC
74.1. Write a JSON REST service
74.2. Write an XML REST service
74.3. Customize the Jackson ObjectMapper
74.4. Customize the @ResponseBody rendering
74.5. Handling Multipart File Uploads
74.6. Switch off the Spring MVC DispatcherServlet
74.7. Switch off the Default MVC configuration
74.8. Customize ViewResolvers
74.9. Use Thymeleaf 3
75. HTTP clients
75.1. Configure RestTemplate to use a proxy
76. Logging
76.1. Configure Logback for logging
76.1.1. Configure logback for file only output
76.2. Configure Log4j for logging
76.2.1. Use YAML or JSON to configure Log4j 2
77. Data Access
77.1. Configure a custom DataSource
77.2. Configure Two DataSources
77.3. Use Spring Data repositories
77.4. Separate @Entity definitions from Spring configuration
77.5. Configure JPA properties
77.6. Configure Hibernate Naming Strategy
77.7. Use a custom EntityManagerFactory
77.8. Use Two EntityManagers
77.9. Use a traditional persistence.xml
77.10. Use Spring Data JPA and Mongo repositories
77.11. Expose Spring Data repositories as REST endpoint
77.12. Configure a component that is used by JPA
78. Database initialization
78.1. Initialize a database using JPA
78.2. Initialize a database using Hibernate
78.3. Initialize a database using Spring JDBC
78.4. Initialize a Spring Batch database
78.5. Use a higher-level database migration tool
78.5.1. Execute Flyway database migrations on startup
78.5.2. Execute Liquibase database migrations on startup
79. Messaging
79.1. Disable transacted JMS session
80. Batch applications
80.1. Execute Spring Batch jobs on startup
81. Actuator
81.1. Change the HTTP port or address of the actuator endpoints
81.2. Customize the �whitelabel� error page
81.3. Actuator and Jersey
82. Security
82.1. Switch off the Spring Boot security configuration
82.2. Change the AuthenticationManager and add user accounts
82.3. Enable HTTPS when running behind a proxy server
83. Hot swapping
83.1. Reload static content
83.2. Reload templates without restarting the container
83.2.1. Thymeleaf templates
83.2.2. FreeMarker templates
83.2.3. Groovy templates
83.3. Fast application restarts
83.4. Reload Java classes without restarting the container
83.4.1. Configuring Spring Loaded for use with Maven
83.4.2. Configuring Spring Loaded for use with Gradle and IntelliJ IDEA
84. Build
84.1. Generate build information
84.2. Generate git information
84.3. Customize dependency versions
84.4. Create an executable JAR with Maven
84.5. Use a Spring Boot application as a dependency
84.6. Extract specific libraries when an executable jar runs
84.7. Create a non-executable JAR with exclusions
84.8. Remote debug a Spring Boot application started with Maven
84.9. Remote debug a Spring Boot application started with Gradle
84.10. Build an executable archive from Ant without using spring-boot-antlib
84.11. How to use Java 6
84.11.1. Embedded servlet container compatibility
84.11.2. Jackson
84.11.3. JTA API compatibility
85. Traditional deployment
85.1. Create a deployable war file
85.2. Create a deployable war file for older servlet containers
85.3. Convert an existing application to Spring Boot
85.4. Deploying a WAR to WebLogic
85.5. Deploying a WAR in an Old (Servlet 2.5) Container
X. Appendices
A. Common application properties
B. Configuration meta-data
B.1. Meta-data format
B.1.1. Group Attributes
B.1.2. Property Attributes
B.1.3. Hint Attributes
B.1.4. Repeated meta-data items
B.2. Providing manual hints
B.2.1. Value hint
B.2.2. Value provider
Any
Class reference
Handle As
Logger name
Spring bean reference
Spring profile name
B.3. Generating your own meta-data using the annotation processor
B.3.1. Nested properties
B.3.2. Adding additional meta-data
C. Auto-configuration classes
C.1. From the �spring-boot-autoconfigure� module
C.2. From the �spring-boot-actuator� module
D. Test auto-configuration annotations
E. The executable jar format
E.1. Nested JARs
E.1.1. The executable jar file structure
E.1.2. The executable war file structure
E.2. Spring Boot�s �JarFile� class
E.2.1. Compatibility with the standard Java �JarFile�
E.3. Launching executable jars
E.3.1. Launcher manifest
E.3.2. Exploded archives
E.4. PropertiesLauncher Features
E.5. Executable jar restrictions
E.5.1. Zip entry compression
E.5.2. System ClassLoader
E.6. Alternative single jar solutions
F. Dependency versions

I. Spring Boot文档

本节简要介绍 Spring Boot 参考文档,可以看作是其余内容的概述。您可以以线性方式阅读此参考指南,如果您不感兴趣可以跳过该部分。

1. 关于文档

Spring Boot参考指南提供了 htmlpdf and epub 格式文档。 最新的副本可在 docs.spring.io/spring-boot/docs/current/reference获取。

只要您不对文档副本收取任何费用,无论是以印刷版还是电子版分发,每个副本都包含本版权声明,本文档的副本可供您自己使用或分发给他人。

2. 获取帮助

在使用Spring Boot遇到了麻烦?我们可以为您提供帮助!

[Note] 注意

Spring Boot的所有都是开源的,包括文档!如果您发现文档中存在错误了;或者您想改进它们, 请 参与

3. 起步

如果您是刚开始使用Spring Boot,或者对'Spring'大体有个印象, 这是您开始的地方!

4. 使用Spring Boot

准备开始使用Spring Boot了么? 我们已经迫不及待了

5. 了解Spring Boot特性

需要更多关于Spring Boot核心特性的详细内容? 这是为您准备的!

6. 转移到生产环境

当您准备好将Spring Boot应用推送到生产环境时,我们有一些 您可能会感兴趣的技巧

7. 高级主题

最后,我们为更高级用户提供了几个主题。

第 II部分. 入门

如果您是刚开始使用Spring Boot,或者对“Spring”有点印象,那么这部分内容是为您准备的!在这里我们将回答基本的“是什么?”,“怎么做?”和“为什么?”这类问题。您将会发现一个友好的Spring Boot简介和安装说明。当我们讨论一些核心原理时,我们将构建第一个Spring Boot应用。

8. Spring Boot简介

Spring Boot可以很容易地创建出可以直接运行的独立、生产级别的基于Spring的应用。我们对Spring平台和第三方类库有自己的看法,所以您可以从最开始的时候开始吧。大多数的Spring Boot应用需要很少的Spring配置。

您可以使用Spring Boot来创建一个可以使用java -jar来运行或者基于传统的war包部署的应用程序。 我们还提供了一个用于运行“spring scripts”的命令行工具。

我们的主要目标是:

  • 为所有Spring Boot开发提供一个更快、更全面的入门体验。
  • 坚持自我虽然很好,但是随着需求开始偏离需要迅速脱离出来。
  • 提供大量非功能性特性系列项目(例如:内嵌服务器、安全型、指标、运行状况检查、外部配置)。
  • 绝对没有代码生成,也不需要XML配置。

9. 系统要求

默认情况下,Spring Boot 1.5.4.RELEASE需要Java 7和Spring Framework 4.3.9.RELEASE或者更高版本。您可以使用Spring Boot和Java 6通过其它配置。 更多详细信息,请参见 第 84.11节,“如何使用Java 6”。为Maven (3.2+),和Gradle 2(2.9或者更好版本)和3提供了显式构建的支持。

[Tip] 提示

虽然您可以在Java6或者7上使用Spring Boot,但是如果可以的话我们强烈推荐您使用Java 8。

9.1 Servlet容器

以下的嵌入式容器支持开箱即用:

名称 Servlet版本 Java版本

Tomcat 8

3.1

Java 7+

Tomcat 7

3.0

Java 6+

Jetty 9.3

3.1

Java 8+

Jetty 9.2

3.1

Java 7+

Jetty 8

3.0

Java 6+

Undertow 1.3

3.1

Java 7+

您还可以将Spring Boot应用部署到任何一个Servlet 3.0+兼容容器。

10. 安装Spring Boot

Spring Boot可以与“经典”的Java开发工具一起使用或者作为命令行工具安装。 无论如何,您将需要Java SDK 1.6或者更高版本。在开始之前您应该检查Java的安装情况:

$ java -version

如果您是Java开发新手,或者您只想尝试使用Spring Boot,您可能需要首先尝试使用Spring Boot CLI,否则请阅读“经典”的安装说明。

[Tip] 提示

虽然Spring Boot支持Java 1.6,但是如果可以,您应该考虑使用最新的Java版本。

10.1 Java开发人员的安装说明

您可以跟使用任何标准Java库的方式一样使用Spring Boot。 只需要在classpath下包含相应的spring-boot-*.jar文件即可。Spring Boot不需要任何特殊的工具来集成,所以您可以使用任何IDE或者文本编辑器;并且Spring Boot应用也没什么特殊之处,因此可以像任何其它Java程序一样运行与调试。

虽然您可以复制Spring Boot的jar文件,但我们通常建议您使用支持依赖管理的构建工具(比如Maven或者Gradle)。

10.1.1 Maven安装

Spring Boot兼容Apache Maven 3.2或者更高版本。如果您还没有安装Maven,可以到maven.apache.org上按照说明进行操作。

[Tip] 提示

在许多操作系统上,Maven可以通过软件包管理器来安装。如果您是OSX Homebrew用户,请尝试使用brew install maven。Ubuntu 用户可以运行 sudo apt-get install maven

Spring Boot依赖使用到了org.springframework.boot groupId。 通常,您的Maven POM文件将从spring-boot-starter-parent项目继承,并声明一个或多个“Starter”的依赖关系。Spring Boot还提供了一个可选的Maven插件来创建可执行jar。

这是一个典型的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.example</groupId>
    <artifactId>myproject</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <!-- 从Spring Boot继承默认配置 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.4.RELEASE</version>
    </parent>

    <!-- 为Web应用程序添加依赖 -->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <!-- 打包成可执行jar文件 -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
[Tip] Tip

The spring-boot-starter-parent是一个使用Spring Boot的好方法,但它并不是任何时候都合适。有时您可能需要继承不同的父POM,或者您不想喜欢我们的默认配置。请参见第 13.2.2节, “使用不带父POM的Spring Boot”作为使用导入域的替代解决方案。 for an alternative solution that uses an import scope.

10.1.2 Gradle安装

Spring Boot兼容Gradle 2 (2.9或者更高版本)和Gradle 3。如果您还没有安装Gradle,您可以按照www.gradle.org/上的说明进行操作。

Spring Boot依赖org.springframework.boot group。 通常,您的项目将声明一个或者多个“Starter”的依赖关系。 Spring Boot提供了一个有用的Gradle插件,可以用于简化依赖关系的声明和创建可执行jar文件。

这是一个典型的build.gradle文件:

plugins {
    id 'org.springframework.boot' version '1.5.4.RELEASE'
    id 'java'
}


jar {
    baseName = 'myproject'
    version =  '0.0.1-SNAPSHOT'
}

repositories {
    jcenter()
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web")
    testCompile("org.springframework.boot:spring-boot-starter-test")
}

10.2 安装Spring Boot CLI

Spring Boot CLI是一个命令行工具,如果您想要使用Spring快速搭建原型,可以使用它。它允许您运行Groovy脚本,这意味着您有类Java语法并且没有太多的样板代码。

您不需要使用CLI来使用Spring Boot,但是它无疑是将Spring应用从本地开始的最好方法。

10.2.1 手动安装

您可以从Spring软件仓库中下载Spring CLI发行版本:

最新的快照发行版也是可用的。

一旦下载之后,请按照解压缩归档文件中的INSTALL.txt说明进行操作。总之:在.zip文件的bin/目录中有一个spring脚本(在Windows下为spring.bat),或者也可以使用java -jar配合.jar文件(该脚本可以帮助您确保classpath设置正确)。

10.2.2 使用SDKMAN!安装

SDKMAN!(软件开发包管理器)用于管理二进制SDK的多个版本,包括Groovy和Spring Boot CLI。从sdkman.io获取SDKMAN!并安装Spring Boot:

$ sdk install springboot
$ spring --version
Spring Boot v1.5.4.RELEASE

如果您正在开发CLI的功能,并希望能轻松地访问刚创建的版本,请参照以下额外指令。

$ sdk install springboot dev /path/to/spring-boot/spring-boot-cli/target/spring-boot-cli-1.5.4.RELEASE-bin/spring-1.5.4.RELEASE/
$ sdk default springboot dev
$ spring --version
Spring CLI v1.5.4.RELEASE

以上将会安装一个称为devspring的本地实例。它指向您的目标构建位置,所以每次重建Spring Boot时,spring都是最新的。

您可以这样做来了解:

$ sdk ls springboot

================================================================================
Available Springboot Versions
================================================================================
> + dev
* 1.5.4.RELEASE

================================================================================
+ - local version
* - installed
> - currently in use
================================================================================

10.2.3 OSX Homebrew安装

如果您是在Mac上工作并且使用Homebrew,您安装Spring Boot CLI需要做的:

$ brew tap pivotal/tap
$ brew install springboot

Homebrew将会把spring安装在/usr/local/bin

[Note] 注意

如果您没有看到执行流程, 您安装的brew可能已经过期了。执行brew update并重新尝试。

10.2.4 MacPorts安装

如果您实在Mac上工作并且使用MacPorts,您安装Spring Boot CLI所需要做的:

$ sudo port install spring-boot-cli

10.2.5 命令行完成

Spring Boot CLI为BASHzsh提供了命令完成脚本。您可以在任何shell中引用此script(也称为spring),或将其放在您个人的或者系统范围的bash完成初始化。在Debian系统上,系统范围的脚本位于/shell-completion/bash中,当新的shell启动时,该目录中的所有脚本将被执行。要手动运行脚本, 例如:您使用SDKMAN!安装了

$ . ~/.sdkman/candidates/springboot/current/shell-completion/bash/spring
$ spring <HIT TAB HERE>
  grab  help  jar  run  test  version
[Note] 注意

如果您使用Homebrew或者MacPorts安装了Spring Boot CLI,则命令行完成脚本将自动注册到您的shell中。

10.2.6 快速开始Spring CLI示例

这是一个非常简单的web应用程序,可以用于测试您的安装。创建一个名为app.groovy的文件:

@RestController
class ThisWillActuallyRun {

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

}

之后在shell中运行它:

$ spring run app.groovy
[Note] 注意

刚开始运行应用的时候需要一些时间,因为下载依赖的关系。后续运行将会更快。

在您喜欢的浏览器中打开localhost:8080,您应该会看到以下输出:

Hello World!

10.3 升级早期版本的Spring Boot

如果您从早期版本的Spring Boot升级,请检查项目wiki上托管的“release notes(发行说明)”。您将会找到升级说明以及每个版本的“新的和值得注意的”功能列表。

要升级现有的CLI,请使用相应的包管理器命令(例如 brew upgrade) 或者, 如果您手动安装了CLI,请按照 标准说明,记得更新您的PATH环境变量以删除任何旧的引用。

11. 开发您的第一个Spring Boot应用

让我们使用Java来开发一个简单的“Hello World!”web应用程序来体现Spring Boot的一些关键特性。我们将使用Maven来构建该项目,因为大多数IDE都支持它。

[Tip] 提示

spring.io网站包含了许多使用Spring Boot的“入门指南”,如果您正在寻找具体问题的方案,先从上面检查一下。

您可以通过到start.spring.io并从依赖关系搜索器中选择webstarter来快速完成以下步骤。这将自动生成一个新的项目结构,以便您可以立即开始编码。查看文档了解更多信息。

在开始之前,打开终端检查您是否安装了有效的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
[Note] 注意

此示例需要在自己的文件夹中创建,后续的说明假设您已经创建了一个合适的文件夹,它是您的“当前目录”。

11.1 创建POM

我们需要先创建一个Maven pom.xml文件。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.example</groupId>
                    <artifactId>myproject
                    </artifactId>
                        <version>0.0.1-SNAPSHOT
                        </version>

                            <parent>
                            <groupId>org.springframework.boot
                            </groupId>
                                <artifactId>spring-boot-starter-parent
                                </artifactId>
                                    <version>1.5.4.RELEASE
                                    </version>
                                        </parent>

                                        <!-- 此处添加其它行... -->

                                        </project>

这应该会给您一个构建工作,您可以通过运行mvn package来测试它(此时您可以忽略“jar will be empty - no content was marked for inclusion!”警告)。

[Note] Note

At this point you could import the project into an IDE (most modern Java IDE�s include built-in support for Maven). For simplicity, we will continue to use a plain text editor for this example.

11.2 添加classpath依赖

Spring Boot提供了多个“Starters”,可以方便地将jar添加到您的classpath下。我们的示例应用已经在POM的parent部分使用了spring-boot-starter-parentparent section of the POM. The spring-boot-starter-parent是一个提供了有用的Maven默认配置值的特殊Starter。它还提供了依赖管理功能,以便您可以省去“维护”这些依赖关系的版本标签。

其他“Starter”只是提供您在开发特定应用时可能需要到的依赖。由于我们正在开发一个web应用,所以我们将添加一个spring-boot-starter-web依赖 � 但在此之前,我们来看看我们目前拥有的。

$ mvn dependency:tree

[INFO] com.example:myproject:jar:0.0.1-SNAPSHOT

mvn dependency:tree命令以树形的形式打印项目的依赖。您可以看到spring-boot-starter-parent本身不提供依赖。我们来编辑我们的pom.xml并添加spring-boot-starter-web依赖,就在parent下:

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

如果您在此运行mvn dependency:tree,您将会看到现在有许多附加的依赖,包括了Tomcat web服务器和Spring Boot本身。

11.3 编码

要完成我们的应用,我们需要创建一个单独的Java文件。默认情况下,Maven将从src/main/java目录下编译源代码,因此您需要穿概念该文件夹结构,之后添加一个名为src/main/java/Example.java的文件:

import org.springframework.boot.*;
                import org.springframework.boot.autoconfigure.*;
                import org.springframework.stereotype.*;
                import org.springframework.web.bind.annotation.*;

                @RestController
                @EnableAutoConfiguration
                public class Example {

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

                public static void                main(String[] args) throws Exception
                { SpringApplication.run(Example.
                class, args); } }

                

虽然这里没有多少代码,但仍有很多事情要做。让我们看看重要的部分。

11.3.1 @RestController和@RequestMapping注解

Example类中的第一个注解是@RestController。这被称作 stereotype注解。它为人们阅读代码提供了一些提示,对于Spring而言,这个类具有特定的作用。在这种情况下,我们的类是一个web @Controller,因此Spring在处理传入的web请求时会考虑它。

@RequestMapping注解提供了“routing(路由)”信息。它告诉Spring,任何具有路径为“/”的HTTP请求都应映射到home方法。@RestController注解告知Spring将渲染生成的字符串直接返回给调用者。

[Tip] 提示

@RestController@RequestMapping直接是Spring MVC注解(它们不是Spring Boot特有的)。有关更多详细信息,请参阅Spring参考文档中的MVC章节

11.3.2 @EnableAutoConfiguration注解

第二个类级别注解是@EnableAutoConfiguration。此注解告诉Spring Boot根据您添加的jar包依赖来“猜测”您将如何配置Spring,由于spring-boot-starter-web添加了Tomcat和Spring MVC,auto-configuration(自动配置) 将假定您正在开发web应用并相应设置了Spring。

11.3.3 “main”方法

我们应用的最后一部分是 main 方法。这只是一个遵循Java惯例的应用程序入口点的标准方法。我们的main方法通过调用 run 来委托Spring Boot的 SpringApplication类,SpringApplication类将引导我们的应用,启动Spring,然后启动自动配置的Tomcat web服务器。我们需要将Example.class 作为一个参数传递给 run 方法来告知 SpringApplication,它是主Spring组件。同时还传递 args 数组以暴露任何命令行参数。

11.4 运行示例

做到这个点上,我们的应用应该是可以工作了。由于我们使用了 spring-boot-starter-parent POM,所以我们有一个好用的 运行 方式,我们可以使用它来启动应用程序。在根目录下输入 mvn spring-boot:run以启动应用:

$ mvn spring-boot:run

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::  (v1.5.4.RELEASE)
....... . . .
....... . . . (log output here)
....... . . .
........ Started Example in 2.222 seconds (JVM running for 6.514)

如果您用浏览器打开了 localhost:8080,您应该会看到以下输出:

Hello World!

要正常退出程序,请按 ctrl-c

11.5 创建可执行jar

让我们完成我们的示例,创建一个完全自包含的可执行jar文件,我们可以在生产环境中运行。可执行jar(有时被称为“fat jars”)是包含编译后的类以及代码运行时所需要相关的jar依赖的归档文件。

要创建可执行jar,我们需要将 spring-boot-maven-plugin 添加到我们的pom.xml文件中。在 dependencies 下方插入以下行:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
[Note] 注意

spring-boot-starter-parent 的POM包括了绑定 重新打包 目标的 <executions> 配置。如果您没有使用parent POM,您将需要自己声明此配置。有关详细的信息,请参阅插件文档

保存您的 pom.xml 并在命令行中运行 mvn package: line:

$ mvn package

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building myproject 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] .... ..
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ myproject ---
[INFO] Building jar: /Users/developer/example/spring-boot-example/target/myproject-0.0.1-SNAPSHOT.jar
[INFO]
[INFO] --- spring-boot-maven-plugin:1.5.4.RELEASE:repackage (default) @ myproject ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

如果您浏览 target 目录,您应该会看到 myproject-0.0.1-SNAPSHOT.jar。 该文件的大小大约为10MB。如果您想要“偷看”里面的内容,您可以使用 jar tvf

$ jar tvf target/myproject-0.0.1-SNAPSHOT.jar

您应该还会在 target 目录中看到一个名为 myproject-0.0.1-SNAPSHOT.jar.original 较小的文件。这是Maven在由Spring Boot重新打包之前所创建的原始jar文件。

要运行该应用,使用 java -jar 命令:

$ java -jar target/myproject-0.0.1-SNAPSHOT.jar

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::  (v1.5.4.RELEASE)
....... . . .
....... . . . (log output here)
....... . . .
........ Started Example in 2.536 seconds (JVM running for 2.864)

跟之前一样, 要正常退出应用,请按 ctrl-c

12. 接下来要看什么

希望本章节为您提供了一些Spring Boot基础知识,且让您准备编写自己的应用。如果您是一个面向任务(task-oriented)的开发人员,您可能想跳过 spring.io,看看一些解决具体的“如何使用Spring”这类问题的入门指南;我们还有Spring Boot-specific How-to参考文档。

Spring Boot仓库还有很多您可以运行的示例。 示例与代码的其余部分是独立的(您不需要构建其余的代码来运行或使用示例)。

下一个步骤是阅读Part III. 使用Spring Boot。 如果您真的不耐烦了,您也可以跳过去阅读Spring Boot功能

第III部分. 使用Spring Boot

本章节将详细介绍如何使用Spring Boot。它覆盖了诸如构建系统、自动配置和如何运行应用等主题。我们还介绍一些Spring Boot最佳实践。虽然Spring Boot没有什么特别(它只是另一个您可以使用的库),但有一些建议可以让您的开发工作变得更加容易。

如果您是刚刚开始使用Spring Boot,那么在深入本部分之前,您应该先阅读入门部分。

13. 构建系统

强烈推荐您选择一个支持依赖管理 的构建系统, 还可以将artifacts发布到“Maven Central”仓库。我们建议您选择Maven或者Gradle。虽然可以让Spring Boot与其它构建系统(如Ant)配合工作,但它们不会得到特别好的支持。

13.1 依赖管理

每一个版本的Spring Boot提供了一个它所支持的依赖内置清单。实际上,您不需要为构建配置提供任何版本的依赖,因为Spring Booot正在为您管理。当您升级Spring Boot时,这些依赖也将以一致的方式进行升级。

[Note] 注意

如果您觉得有必要,您仍然可以指定一个版本并覆盖Spring Boot的推荐。

内置清单包含了全部可以与Spring Boot使用的spring模块以及第三方类库的精简列表。该列表可作为一个标准材料清单(spring-boot-dependencies,并且还提供了对 MavenGradle 的额外专门支持。

[Warning] 警告

Spring Boot的每一个版本与Spring Framework的基础版本相关联,因此我们 强烈 建议您不要指定指定其版本。

13.2 Maven

Maven用户可以从 spring-boot-starter-parent 项目继承以获取合理的默认值,父项目提供了以下功能:

  • Java 1.6作为默认编译器级别。
  • 源代码使用UTF-8编码。
  • 依赖管理部分允许您省略常见依赖关系的 <version> 标签,继承自 spring-boot-dependencies 的POM。
  • 智能 资源过滤
  • 智能插件配置(exec pluginsurefireGit commit IDshade)。
  • 针对 application.propertiesapplication.yml 资源的智能过滤,包括特定的文件(例如 application-foo.propertiesapplication-foo.yml

最后一点:由于默认配置文件接受Spring样式占位符(${​}) Maven过滤更改为使用 @..@ 占位符(您可以使用Maven的 resource.delimiter 属性覆盖它)。

13.2.1 继承starter parent

要将项目配置继承 spring-boot-starter-parent,只需要设置 parent

<!-- 继承来自Spring Boot默认配置 -->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.4.RELEASE</version>
</parent>
[Note] 注意

您只需要在此依赖上指定Spring Boot版本号。如果您导入其它的starter,则可以安全地省略版本号。

通过该设置,您还可以通过覆盖自己项目中的配置属性来覆盖单个依赖。例如,要升级到另一个Spring Data发行版本,您需要将以下内容添加到您的 pom.xml文件中。

<properties>
                    <spring-data-releasetrain.version>Fowler-SR2
                    </spring-data-releasetrain.version>
                        </properties>
[Tip] 提示

检查 spring-boot-dependencies的pom 以获取受支持的属性清单。

13.2.2 使用没有父POM的Spring Boot

不是每个人都喜欢从 spring-boot-starter-parent 继承POM配置。您可能需要使用自己公司标准的父POM,或者您可能只是希望明确地声明所有的Maven配置。

如果您不想使用 spring-boot-starter-parent,则仍然可以通过使用 scope=import 依赖来维持依赖管理(但不是插件管理)的好处:

<dependencyManagement>
     <dependencies>
        <dependency>
            <!-- Import dependency management from Spring Boot -->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>1.5.4.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

该设置不允许您使用如上属性来覆盖单个依赖。要实现相同的效果,您需要在您项目的 dependencyManagement 配置项中的 spring-boot-dependencies 依赖配置之前 添加配置。比如,要升级到另一个Spring Data发行版,您需要将以下内容添加到您的 pom.xml文件中。

<dependencyManagement>
    <dependencies>
        <!-- 覆盖Spring Boot提供的Spring Data发行版本 -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-releasetrain</artifactId>
            <version>Fowler-SR2</version>
            <scope>import</scope>
            <type>pom</type>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>1.5.4.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
[Note] 注意

以上示例中,我们指定了一个 BOM,但是任何的依赖类型都可以用这个方法来覆盖。

13.2.3 变更Java版本

spring-boot-starter-parent 选择比较保守的Java兼容性。如果您想听取我们的建议使用更高的Java版本,您可以添加 java.version 属性:

<properties>
    <java.version>1.8</java.version>
</properties>

13.2.4 使用Spring Boot Maven插件

Spring Boot包括了一个 Maven插件,它可以将项目打包成一个可执行jar。如果要使用它,请将插件添加到您的 <plugins> 中:

<build>
                <plugins>
                <plugin>
                <groupId>org.springframework.boot
                </groupId>
                    <artifactId>spring-boot-maven-plugin
                    </artifactId>
                        </plugin>
                        </plugins>
                        </build>
[Note] 注意

如果您使用Spring Boot starter的父pom,则只需要添加插件。除非您要修改父级中定义的设置,否则不需要进行配置。

13.3 Gradle

Gradle用户可以直接在其 dependencies 导入“starters”。不像Maven,没有“super parent”导入来共享一些配置。

repositories {
    jcenter()
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web:1.5.4.RELEASE")
}

spring-boot-gradle-plugin 也是可用的,它提供了从源代码创建可执行并运行项目的任务。它还提供了 依赖管理,除了其它功能外,还允许您省略有Spring Boot管理的任何依赖的版本号:

plugins {
    id 'org.springframework.boot' version '1.5.4.RELEASE'
    id 'java'
}


repositories {
    jcenter()
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web")
    testCompile("org.springframework.boot:spring-boot-starter-test")
}

13.4 Ant

可以使用Apache Ant+Ivy构建Spring Boot项目。spring-boot-antlib “AntLib” 模块也可以用于帮助Ant创建可执行jar文件。

要声明依赖,可参考一下典型的 ivy.xml 文件内容:

<ivy-module version="2.0"
            >
                <info organisation="org.springframework.boot"                module="spring-boot-sample-ant" />
                <configurations>
                <conf name="compile"                description="everything needed to compile this module" />
                <conf name="runtime"                extends="compile" description=
                "everything needed to run this module" />
                    </configurations>
                    <dependencies>
                    <dependency org="org.springframework.boot"                    name="spring-boot-starter"
                    rev="${spring-boot.version}" conf=
                    "compile" />
                        </dependencies>
                        </ivy-module>

典型的 build.xml 大概是这样:

<project
    xmlns:ivy="antlib:org.apache.ivy.ant"
    xmlns:spring-boot="antlib:org.springframework.boot.ant"
    name="myapp" default="build">

    <property name="spring-boot.version" value="1.3.0.BUILD-SNAPSHOT" />

    <target name="resolve" description="--> retrieve dependencies with ivy">
        <ivy:retrieve pattern="lib/[conf]/[artifact]-[type]-[revision].[ext]" />
    </target>

    <target name="classpaths" depends="resolve">
        <path id="compile.classpath">
            <fileset dir="lib/compile" includes="*.jar" />
        </path>
    </target>

    <target name="init" depends="classpaths">
        <mkdir dir="build/classes" />
    </target>

    <target name="compile" depends="init" description="compile">
        <javac srcdir="src/main/java" destdir="build/classes" classpathref="compile.classpath" />
    </target>

    <target name="build" depends="compile">
        <spring-boot:exejar destfile="build/myapp.jar" classes="build/classes">
            <spring-boot:lib>
                <fileset dir="lib/runtime" />
            </spring-boot:lib>
        </spring-boot:exejar>
    </target>
</project>
[Tip] Tip

如果您不想使用 spring-boot-antlib 模块,请参阅第84.10节 使用Ant构建可执行归档,无需使用spring-boot-antlib 和“How-to”。

13.5 Starter

Starter是一组惯例依赖描述符,可以包含在应用中。从starter中,您可以获得所需的所有Spring和相关技术的一站式服务,无须通过示例代码搜索并复制粘贴依赖。比如,如果您要开始使用Spring和JPA进行数据库访问,那么只需要在项目中包含 spring-boot-starter-data-jpa 依赖项即可。

starter包含了很多依赖,您需要使项目快速启动并且运行,并且支持管理的过渡依赖。

Spring Boot在 org.springframework.boot group下提供了以下starter:

表 13.1. Spring Boot应用starters

名称 描述 Pom

spring-boot-starter

核心starter,包含了自动配置支持,日志和YAML

Pom

spring-boot-starter-activemq

使用Apache ActiveMQ作为JMS服务

Pom

spring-boot-starter-amqp

使用到Spring AMQP与Rabbit MQ

Pom

spring-boot-starter-aop

Spring AOP面向切面(aspect-oriented)编程与AspectJ

Pom

spring-boot-starter-artemis

Apache Artemis作为JMS服务

Pom

spring-boot-starter-batch

使用Spring Batch

Pom

spring-boot-starter-cache

使用到Spring Framework的缓存支持

Pom

spring-boot-starter-cloud-connectors

使用Spring Cloud Connector方便连接到如Cloud Foundry和Heroku等云平台

Pom

spring-boot-starter-data-cassandra

使用Cassandra分布式数据库与Spring Data Cassandra

Pom

spring-boot-starter-data-couchbase

使用Couchbase面向文档(document-oriented)数据库与Spring Data Couchbase

Pom

spring-boot-starter-data-elasticsearch

使用Elasticsearch搜索分析引擎与Spring Data Elasticsearch

Pom

spring-boot-starter-data-gemfire

使用GemFire分布式数据存储与Spring Data GemFire

Pom

spring-boot-starter-data-jpa

使用Spring Data JPA与Hibernate

Pom

spring-boot-starter-data-ldap

使用Spring Data LDAP

Pom

spring-boot-starter-data-mongodb

使用MongoDB面向文档(document-oriented)数据库与Spring Data MongoDB

Pom

spring-boot-starter-data-neo4j

使用Neo4j图数据库与Spring Data Neo4j

Pom

spring-boot-starter-data-redis

使用Redis键值数据存储与Spring Data Redis与Jedis client

Pom

spring-boot-starter-data-rest

使用Spring Data REST以REST的方式暴露Spring Data仓库

Pom

spring-boot-starter-data-solr

使用Apache Solr搜索平台与Spring Data Solr

Pom

spring-boot-starter-freemarker

使用FreeMarker视构建MVC web应用

Pom

spring-boot-starter-groovy-templates

Groovy Templates视图构建MVC web应用

Pom

spring-boot-starter-hateoas

使用Spring MVC与Spring HATEOAS构建基于超媒体的RESTful web应用

Pom

spring-boot-starter-integration

使用Spring Integration

Pom

spring-boot-starter-jdbc

使用JDBC与Tomcat JDBC连接池

Pom

spring-boot-starter-jersey

使用JAX-RS and Jersey构建RESTful web应用,替代 spring-boot-starter-web

Pom

spring-boot-starter-jooq

使用jOOQ访问SQL数据库,替代 spring-boot-starter-data-jpa or spring-boot-starter-jdbc

Pom

spring-boot-starter-jta-atomikos

使用JTA事务与Atomikos

Pom

spring-boot-starter-jta-bitronix

使用JTA事务与Bitronix

Pom

spring-boot-starter-jta-narayana

Spring Boot Narayana JTA Starter

Pom

spring-boot-starter-mail

使用Java Mail与Spring Framewor的邮件发送功能

Pom

spring-boot-starter-mobile

使用Spring Mobile构建web应用

Pom

spring-boot-starter-mustache

使用Mustache视图构建MVC web应用

Pom

spring-boot-starter-security

使用Spring Security

Pom

spring-boot-starter-social-facebook

使用Spring Social Facebook

Pom

spring-boot-starter-social-linkedin

使用Spring Social LinkedIn

Pom

spring-boot-starter-social-twitter

使用Spring Social Twitter

Pom

spring-boot-starter-test

使用JUnit、Hamcrest和Mockito等库测试Spring Boot应用

Pom

spring-boot-starter-thymeleaf

使用Thymeleaf视图构建MVC web应用

Pom

spring-boot-starter-validation

使用Java Bean Validation与Hibernate Validator

Pom

spring-boot-starter-web

使用Spring MVC构建RESTful web应用,使用Tomcat作为默认嵌入容器

Pom

spring-boot-starter-web-services

使用Spring Web Services

Pom

spring-boot-starter-websocket

使用Spring Framework的WebSocket支持构建WebSocket应用

Pom


除了应用方面的starter,以下starter可用于添加 生产就绪 功能:

表 13.2. Spring Boot生产starter

名称 描述 Pom

spring-boot-starter-actuator

使用Spring Boot的Actuator帮助您监控和管理您的应用,它提供了生产就绪功能

Pom

spring-boot-starter-remote-shell

使用CRaSH远程shell通过SSH监控和管理您的应用,1.5之后已被弃用

Pom


最后,Spring Boot还包括了一些starter,如果想要排除或者切换特定的技术,您可以使用:

表 13.3. Spring Boot技术类starter

名称 描述 Pom

spring-boot-starter-jetty

使用Jetty作为嵌入式servlet容器。代替 spring-boot-starter-tomcat

Pom

spring-boot-starter-log4j2

使用Log4j2作为日志,替代 spring-boot-starter-logging

Pom

spring-boot-starter-logging

使用Logback做日志,默认的日志starter

Pom

spring-boot-starter-tomcat

使用Tomcat作为嵌入式servlet容器,为 spring-boot-starter-web starter默认使用的servlet容器

Pom

spring-boot-starter-undertow

使用Undertow作为嵌入式servlet容器,替代 spring-boot-starter-tomcat

Pom


[Tip] 提示

有关其它社区贡献的starter列表,请参阅GitHub上的 spring-boot-starters 模块中的 README文件

14. 结构化您的代码

Spring Boot不需要任何特定的代码布局,但是有一些最佳实践可以帮助您。

14.1 使用“default(默认)”包

当类没有 package 声明时,它被认为是在“default”包中。 通常不鼓励使用“default包”,应该避免使用。对于使用 @ComponentScan@EntityScan 或者 @SpringBootApplication 注解的SPring Boot应用,可能会导致特殊的问题,因为每一个jar的每一个类将被读取。

[Tip] 提示

我们建议您使用Java推荐的包命名约定,并使用反向域名(例如,com.example.project)。

14.2 定位主应用类

我们通常建议您将主应用类定位到其它类之上的根包中, @EnableAutoConfiguration 注解通常放置在您的主类上,它隐式定义了某些项目的基本“搜索包”。例如,如果您在编写一个JPA应用程序,则被 @EnableAutoConfiguration 注解的类的包将被用于搜索标记 @Entity 注解的类。

使用根包还可以允许使用 @ComponentScan 注解,而不需要指定 basePackage 属性。如果您的主类在根包中,也可以使用 @SpringBootApplication 注解。

以下是一个经典的布局:

com
 +- example
     +- myproject
         +- Application.java
         |
         +- domain
         |   +- Customer.java
         |   +- CustomerRepository.java
         |
         +- service
         |   +- CustomerService.java
         |
         +- web
             +- CustomerController.java

Application.java 文件声明了 main 方法和基本的 @Configuration

package com.example.myproject;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

15. 配置类

Spring Boot支持基于Java的配置。虽然可以使用XML配置源来调用 SpringApplication.run(),但我们通常建议您的主配置源是 @Configuration 类。通常,定义了 main 方法的类也是作为 @Configuration 一个很好的候选者。

[Tip] 提示

许多Spring的XML配置示例已经在Internet上发布了。如果可能的话,您无论如何应该尝试着使用等效的基于Java的配置方式,搜索 Enable* 注解可能是一个好的开端。

15.1 导入其它配置类

您不需要将所有的 @Configuration 放在一个类中。@Import 注解可用于导入其它配置类。或者,您可以使用 @ComponentScan 自动扫描所有的Spring组件,包括 @Configuration 类。

15.2 导入XML配置

如果您一定要使用基于XML的配置,我们建议您仍然使用 @Configuration 类。您可以使用额外的 @ImportResource 注解来加载XML配置文件。

16. 自动配置

Spring Boot自动配置尝试根据您添加的jar依赖自动配置Spring应用。例如,如果 HSQLDB 在您的classpath下,并且您没有手动配置任何数据库连接bean,那么我们将自动配置一个内存数据库。

您需要通过将 @EnableAutoConfiguration 或者 @SpringBootApplication 注解添加到您其中一个 @Configuration 类之中以选择自动配置。

[Tip] 提示

您应该只添加一个 @EnableAutoConfiguration 注解。 我们通常建议您将其添加到主要的 @Configuration 类中。

16.1 逐渐替代自动配置

自动配置是非入侵的,您可以随时定义自己的配置来代替自动配置的特定部分。例如,如果您添加自己的 DataSource bean,将不会使用默认的嵌入式数据库。

如果您需要了解当前正在应用的自动配置,以及为什么使用,请使用 --debug 开关启动应用。这将会选择一个核心的logger来启用调试日志,并将自动配置报告记录到控制台。

16.2 禁用指定的自动配置

如果您发现在正在应用不需要的自动配置类,可以通过使用 @EnableAutoConfiguration 的exclude属性来禁用它们。

import org.springframework.boot.autoconfigure.*;
import org.springframework.boot.autoconfigure.jdbc.*;
import org.springframework.context.annotation.*;

@Configuration
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class MyConfiguration {
}

如果类不在classpath下,您可以使用注解的 excludeName 属性并指定完全限定的类名来代替。最后,您还可以通过 spring.autoconfigure.exclude property控制要排除的自动配置列表。

[Tip] 提示

您可以使用注解和property定义排除项

17. Spring Bean与依赖注入

您可以自由使用任何标准的Spring Framework技术来定义您的bean以及它们注入的依赖。为了简单起见,我们经常发现使用 @ComponentScan 寻找您的bean,结合 @Autowired 构造器注入效果更好。

如果您按照上述的建议(将应用类放在根包中),则可以添加 @ComponentScan 而不需要使用任何参数。所有应用组件(@Component@Service@Repository@Controller等)将自动注册为Spring Bean。

以下是一个 @Service Bean,其使用构造注入方式获取一个必需的 RiskAssessor bean。

package com.example.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class DatabaseAccountService implements AccountService {

    private final RiskAssessor riskAssessor;

    @Autowired
    public DatabaseAccountService(RiskAssessor riskAssessor) {
        this.riskAssessor = riskAssessor;
    }

    // ...

}

如果bean中有一个构造方法,您可以忽略掉 @Autowired 注解。

@Service
public class DatabaseAccountService implements AccountService {

    private final RiskAssessor riskAssessor;

    public DatabaseAccountService(RiskAssessor riskAssessor) {
        this.riskAssessor = riskAssessor;
    }

    // ...

}
[Tip] 提示

请注意,构造注入允许 riskAssessor 字段被修饰为 final,这表示以后它不能被更改。

18. 使用@SpringBootApplication注解

许多Spring Boot开发者总是使用 @Configuration@EnableAutoConfiguration@ComponentScan 注解标记在他们的主类上。由于 这些注解经常一起使用(特别是如果您遵循上述的 最佳实践),Spring Boot提供了一个方便的 @SpringBootApplication 注解来替代。

@SpringBootApplication 注解相当于使用 @Configuration@EnableAutoConfiguration@ComponentScan 及其默认属性:

package com.example.myproject;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication // same as @Configuration @EnableAutoConfiguration @ComponentScan
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}
[Note] 注意

@SpringBootApplication 还提供了别名来定制 @EnableAutoConfiguration@ComponentScan 的属性。

19. 运行您的应用

将应用程序打包成jar可执行文件并使用嵌入式HTTP服务器的最大有点之一就是可以按照您想使用的其它方式来运行应用。调试Spring Boot也是很简单的;您不需要任何特殊的IDE插件或者扩展。

[Note] 注意

本章节仅涵盖基于jar的打包内容,如果您选择将应用打包为war文件,则应该参考您的服务器您的服务器和IDE文档。

19.1 使用IDE运行

您可以使用IDE运行Spring Boot应用并作为一个简单的Java应用程序,但是首先您需要导入项目,导入步骤取决于您的IDE和构建系统。大多数的IDE可以直接导入Maven项目,例如Eclipse用户可以从 File 菜单中选择 Import ​Existing Maven Projects

如果您无法将项目直接导入到IDE中,则可以使用构建插件生成IDE元数据(metadata)。Maven包含了EclipseIDEA的插件;Gradle 为各种IDE提供了插件。

[Tip] 提示

如果您不小心运行了两次web应用,您将看到一个“Port already in use”错误。 STS用户可以使用 Relaunch 按钮而不是 Run 按钮,以确保现有的任何实例都已关闭。

19.2 作为打包应用运行

如果您使用Spring Boot Maven或者Gradle插件创建可执行jar,可以使用 java -jar 命令。例如:

$ java -jar target/myproject-0.0.1-SNAPSHOT.jar

也可以在运行打包应用程序时开启运城调试支持。这允许您将调试器附加到您打包的应用中。

$ java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=n \
       -jar target/myproject-0.0.1-SNAPSHOT.jar

19.3 使用Mavne插件

Spring Boot Maven插件包含了一个 run 指令,可以用快速编译和运行应用。应用将会迅速运行,就像在IDE中。

$ mvn spring-boot:run

您可能还需要使用到有用的操作系统变量:

$ export MAVEN_OPTS=-Xmx1024m -XX:MaxPermSize=128M

19.4 使用Gradle插件

Spring Boot Gradle插件还包括了一个可以以爆炸(飞快)形式运行应用的 bootRun 任务。每当导入 spring-boot-gradle-plugin 时,都会添加 bootRun 任务:

$ gradle bootRun

您可能还想使用这个有用的操作系统变量:

$ export JAVA_OPTS=-Xmx1024m -XX:MaxPermSize=128M

19.5 热拔插

由于Spring Boot应用程序只是纯的Java应用,所以JVM热拔插应该可以开箱即用。JVM热拔插在一定程度上受到了可代替字节码的限制,为了更完整的解决方案,可以使用 JRebel 或者 Spring Loaded 项目。 spring-boot-devtools 模块还支持快速重启应用。

有关详细信息,请参阅 第20章 开发者工具如何使用热拔插

20. 开发者工具

Spring Boot包含了一组额外的工具,可以使应用开发体验更加愉快。spring-boot-devtools 模块包含在任何项目中,以提供额外的开发时(development-time)功能。要使用devtools支持,只需要将模块依赖描述添加到您的构建中即可:

Maven. 

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

Gradle. 

dependencies {
    compile("org.springframework.boot:spring-boot-devtools")
}

[Note] 注意

运行完全打包的应用时,开发者工具会自动禁用。如果您的应用是使用 java -jar 启动,或者是使用特殊的类加载器启动,那么它会被认为是一个“生产应用”。将依赖标记为可选是一种最佳方式,在使用您的项目时,防止devtools被应用到其它模块。Gradle不支持开箱即用的 optional(可选的) 依赖,这时候您可能希望查看 propdeps-plugin 这方面的内容。

[Tip] 提示

重新打包的归档默认情况下不包含devtools。如果要使用远程devtools功能, 你需要禁用 excludeDevtools 构建属性已包含它。该属性支持Maven和Gradle插件。

20.1 Property默认值

Spring Boot所支持的几个库是使用缓存来提高性能的。例如,模板引擎 将缓存编译的模板,以避免重复解析模板文件。此外,Spring MVC可以在服务静态资源时添加HTTP缓存头。

虽然缓存在生产中非常有用,但它在开发过程可能会产生相反的效果,从而阻止您看到刚才在应用中作出的更改。因此,spring-boot-devtools将默认禁用这些缓存选项。

缓存选项通常是在您的 application.properties 文件中设置。例如,Thymeleaf提供了 spring.thymeleaf.cache 属性。您不需要手动设置这些属性,spring-boot-devtools 会自动应用合适的开发时(development-time)配置。

[Tip] 提示

有关应用属性的完整列表,请参阅DevToolsPropertyDefaultsPostProcessor

20.2 自动重启

使用 spring-boot-devtools 的应用将在classpath下的文件发生更改时自动重启。这在IDE中工作时可能是一个非常有用的功能,因为它为代码变更提供了非常块的反馈循坏。默认情况下,将监视classpath指向文件夹下任意一个入口。请注意,某些资源(如静态资源和视图模板)不需要重启应用

[Note] 注意

只要forking被开启,您可以通过受支持的构建工具(如Maven和Gradle)启用应用,因为DevTools需要一个独立的应用类加载器才能正常运行。

[Tip] 提示

自动重启功能与LiveReload一起使用时非常棒。阅读下文获取更多信息。 如果您使用JRebel,自动重启将会被禁用以利于动态类的加载,但任然可以使用devtools的其它功能(如LiveReload和property覆盖)

[Note] 注意

DevTools依赖于应用(context)上下文的关闭钩子,在重启期间关闭它。如果禁用了关闭钩子(SpringApplication.setRegisterShutdownHook(false)),它将不能正常工作。

[Note] 注意

当决定classpath下的条目被更改时是否应该触发重启时,DevTools会自动忽略名为 spring-bootspring-boot-devtoolsspring-boot-autoconfigurespring-boot-actuator, 和 spring-boot-starter的项目。

[Note] 注意

DevTools需要自定义 ApplicationContext 使用的 ResourceLoader:如果您的应用已经提供了一个,它被包装起来。不支持在 ApplicationContext 上直接覆盖 getResource 方法。

20.2.1 排除资源

某些资源在更改时不一定需要触发重启。例如,Thymeleaf模板可以被就地编辑。默认情况下,更改 /META-INF/maven/META-INF/resources/resources ,/static/public 或者 /templates 不会触发重启,但会触发 实时重载。如果您想自定义排除项,可以使用 spring.devtools.restart.exclude 属性。例如,仅排除 /static/public,您可以设置以下内容:

spring.devtools.restart.exclude=static/**,public/**
[Tip] 提示

如果要保留这些默认值并 添加 其他排除项 ,请改用 spring.devtools.restart.additional-exclude 属性。

20.2.2 监视附加路径

当您对不在classpath中的文件文件进行修改时,可能需要重启或者重新加载应用。为此,请使用 spring.devtools.restart.additional-paths 属性来配置监视其他路径的更改情况。您可以使用上述spring.devtools.restart.exclude 属性 来控制附加路径下的文件被修改时是否触发重启或者只是 实时重载

20.2.3 禁止重启

如果不想使用重启功能,可以使用 spring.devtools.restart.enabled 属性来禁用它。大多数情况下,您可以在 application.properties 中设置此项(重启类加载器仍将被初始化,但不会监视文件更改)。

例如,您需要 完全 禁用重启支持,可能它不适用于某些类库,您需要在调用 SpringApplication.run(​) 之前设置 System 属性。例如:

public static void main(String[] args) {
    System.setProperty("spring.devtools.restart.enabled", "false");
    SpringApplication.run(MyApp.class, args);
}

20.2.4 使用触发文件

如果您使用IDE来不断编译被更改的文件,也许您只是希望在特定的时间内触发重启。为此,您可以使用“触发文件”,这是一个特殊的文件,当您真的要触发重启检查时,必须修改它。更改文件只会触发检查,只有在 Devtools检查到它必须指定某些操作时才会触发重启,触发文件可以手动更新,也可以通过IDE插件更新。

要使用触发文件,请使用 spring.devtools.restart.trigger-file 属性。

[Tip] 提示

您可能希望将 spring.devtools.restart.trigger-file 设置为 全局配置,以使得所有的项目都能应用此方式。

20.2.5 自定义重启类加载器

如上面的 重新启动和重启加载 部分所述,重启功能是通过使用两个类加载器实现的。对于大多数应用而言,此方法工作良好,然而,有时可能会导致类加载出现问题。

默认情况下,IDE中的任何打开的项目将使用“重启”类加载器加载,任何常规的 .jar 文件将使用“base”类加载器加载。如果您是在多模块项目中工作,而不是每一个模块都导入到您的IDE中,则您可能需要定义一些东西。为此,您可以创建一个 META-INF/spring-devtools.properties 文件。

spring-devtools.properties 文件可以包含以 restart.exclude.restart.include. 为前缀的属性。include 元素 应该被推到“重启”类加载器,exclude 元素应该被下推到“基础(base)”类加载器。属性的值是一个被应用到classpath的正则表达式。

例如:

restart.exclude.companycommonlibs=/mycorp-common-[\\w-]+\.jar
restart.include.projectcommon=/mycorp-myproj-[\\w-]+\.jar
[Note] 注意

所有的属性键名必须是唯一的。只要有一个属性以 restart.include.restart.exclude. 开头,它将会被考虑。

[Tip] 提示

想要加载classpath中的所有 META-INF/spring-devtools.properties 文件为项目所有,您可以它们打包进工程或者类库中。

20.2.6 已知限制

重新启动功能对于使用标准 ObjectInputStream 反序列化的对象无效。如果需要反序列化数据,可能需要使用Spring的 ConfigurableObjectInputStreamThread.currentThread().getContextClassLoader() 组合。

不幸的是,有几个第三方类库在不考虑上下文类加载器的情况下使用了反序列化。如果您发现这样的问题,您需要向原作者请求修复。

20.3 LiveReload

spring-boot-devtools 模块包括一个嵌入式实时重载(LiveReloaded)服务器,可以在资源更改时用于触发浏览器刷新。您可以从 livereload.com免费获取Chrome,Firefox和Safari平台下对应的LiveReload浏览器扩展程序。

如果您不想在应用运行时启动LiveReload服务器,可以将 spring.devtools.livereload.enabled 属性设置为 false

[Note] 注意

一次只能运行一个LiveReload服务器。开始启动应用之前,请确保没有其他LiveReload服务器正在运行。如果在IDE中启动多个应用,那么只有第一个应用程序支持LiveReload。

20.4 全局设置

您可以通过在 $HOME 文件中夹添加名为 .spring-boot-devtools.properties 的文件来配置全局devtools设置(请注意,文件名以“.”开头)。在此文件中添加的任何属性将应用到您的计算机上使用了devtools的 所有 Spring Boot应用。 例如,始终使用触发文件来配置重启功能,您可以添加以下内容:

~/.spring-boot-devtools.properties. 

spring.devtools.reload.trigger-file=.reloadtrigger

20.5 远程应用

Spring Boot开发者工具不仅限于本地开发使用。远程运行应用时也可以使用到多种功能。远程支持是可选的,为了确保您重新打包的归档文件能够包含 devtools

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <excludeDevtools>false</excludeDevtools>
            </configuration>
        </plugin>
    </plugins>
</build>

之后您需要设置一个 spring.devtools.remote.secret 属性,例如:

spring.devtools.remote.secret=mysecret
[Warning] 警告

在远程应用上启用 spring-boot-devtools 是存在安全隐患的。您不应该在生产部署中启用它。

远程devtools支持分为两部分:一个接受连接的服务器端端点和在IDE中运行的客户端应用。当设置了 spring.devtools.remote.secret 属性时,服务器组件将自动启用。客户端组件必须手启用。

20.5.1 运行远程客户端应用

远程客户端应用在您的IDE中运行。您需要与要连接的远程项目在相同的classpath下运行 org.springframework.boot.devtools.RemoteSpringApplication。传递给应用程序的 非可选 参数应该是您要连接的远程URL。

例如,如果您使用的是Eclipse或STS,并且有一个名为 my-app 的项目已部署到Cloud Foundry,则可以执行以下操作:

  • Run 菜单中选择选择 Run Configurations ​
  • 创建一个新的 Java Application “launch configuration”。
  • 浏览 my-app 项目。
  • 使用 org.springframework.boot.devtools.RemoteSpringApplication 作为主类。
  • https://myapp.cfapps.io 作为 程序参数 (或者任何远程URL)传入。

运行的远程客户端将如下所示:

  .   ____          _                                              __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _          ___               _      \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` |        | _ \___ _ __  ___| |_ ___ \ \ \ \
 \\/  ___)| |_)| | | | | || (_| []::::::[]   / -_) '  \/ _ \  _/ -_) ) ) ) )
  '  |____| .__|_| |_|_| |_\__, |        |_|_\___|_|_|_\___/\__\___|/ / / /
 =========|_|==============|___/===================================/_/_/_/
 :: Spring Boot Remote :: 1.5.4.RELEASE

2015-06-10 18:25:06.632  INFO 14938 --- [main] o.s.b.devtools.RemoteSpringApplication   : Starting RemoteSpringApplication on pwmbp with PID 14938 (/Users/pwebb/projects/spring-boot/code/spring-boot-devtools/target/classes started by pwebb in /Users/pwebb/projects/spring-boot/code/spring-boot-samples/spring-boot-sample-devtools)
2015-06-10 18:25:06.671  INFO 14938 --- [main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@2a17b7b6: startup date [Wed Jun 10 18:25:06 PDT 2015]; root of context hierarchy
2015-06-10 18:25:07.043  WARN 14938 --- [main] o.s.b.d.r.c.RemoteClientConfiguration    : The connection to http://localhost:8080 is insecure. You should use a URL starting with 'https://'.
2015-06-10 18:25:07.074  INFO 14938 --- [main] o.s.b.d.a.OptionalLiveReloadServer       : LiveReload server is running on port 35729
2015-06-10 18:25:07.130  INFO 14938 --- [main] o.s.b.devtools.RemoteSpringApplication   : Started RemoteSpringApplication in 0.74 seconds (JVM running for 1.105)
[Note] 注意

由于远程客户端与实际应用使用的是同一个classpath,因此可以直接读取应用的properties。这也是 spring.devtools.remote.secret 属性如何被读取和传递给服务器进行身份验证的原因。

[Tip] 提示

建议使用 https:// 作为连接协议,以便加密传输过程并防止密码被拦截。

[Tip] 提醒

如果您需要使用代理来访问远程应用,请配置 spring.devtools.remote.proxy.host and spring.devtools.remote.proxy.port 属性。

20.5.2 远程更新

远程客户端将使用与本地重启相同的方式来监控应用classpath下发生的更改。任何更新的资源将被推送到远程应用,(如果需要) 触发重启。如果您正在迭代一个使用了本地没有的云服务的功能,这可能会非常有用。通常远程更新和重启比完全重新构建和部署的周期要快得多。

[Note] 注意

远程客户端只有在运行时才监控文件。如果您在启动远程客户端之前更改了文件,文件将不会被推送到远程服务器。

20.5.3 远程调试隧道

在诊断远程应用问题时,Java远程调试是非常有用的。但不幸的是,当您的应用部署到数据中心之外时,并不总是能够进行远程调试。如果您正在是使用基于容器的技术,远程调试也可能难以设置。

为了解决这些限制,devtools支持通过HTTP隧道传送远程调试信息。远程客户端为本地服务曝露了 8000 端口,您可以通过它连接远程调试器。一旦建立连接之后,将通过HTTP将调试信息发送到远程应用。如果您想指定一个不同的端口,可以通过设置 spring.devtools.remote.debug.local-port 属性来实现。

您需要确保远程应用已经开启了远程调试功能。通常可以通过配置 JAVA_OPTS 来实现。例如,在使用Cloud Foundry时,您可以将以下内容添加到 manifest.yml 文件中:

---
    env:
        JAVA_OPTS: "-Xdebug -Xrunjdwp:server=y,transport=dt_socket,suspend=n"
[Tip] 提示

请注意,您不需要给 -Xrunjdwp 指定 address=NNNN 选项。如果此选项被忽略了,Java将简单地挑选一个随机的空闲端口。

[Note] 注意

通过Internet来调试远程服务可能会很慢,您需要在IDE中增加超时配置。例如,在Eclipse中,您可以在 Preferences ​ 中选择 JavaDebug,并将 Debugger timeout (ms) 更改为合适的值(大多数情况下,60000 比较合适)。

[Warning] 警告

当时用IntelliJ IDEA的远程调试隧道时,必须将所有的断点配置为线程挂起而不是JVM挂起。默认情况下,IntelliJ IDEA中的断点会挂起整个JVM,而不仅是暂停触发断点的线程。这会产生不必要的副作用,阻止远程调试管理隧道线程,导致调试会话被冻结。当使用IntelliJ IDEA的远程调试隧道时,应将所有的断点配置为线程挂起而不是JVM挂起。有关详细信息,请参阅 IDEA-165769

21. 打包应用用于生产

可执行jar可用于生产部署。它们是独立(self-contained,独立,自包含)的,它们也非常适合基于云的部署。

对于其他“产就绪”功能,比如健康、审计和REST或者JMX端点度量;可以添加 spring-boot-actuator。有关详细信息,请参见 第 V部分、“Spring Boot Actuator:生产就绪功能”

22. 接下来看什么

您现在应该很好地了解了如何使用Spring Boot以及应该遵循的一些最佳实践。您现在可以深入了解具体的 Spring Boot功能,或者您可以跳过并阅读“生产就绪功能” 方面的内容。

第 IV部分 Spring Boot功能

本节介绍Spring Boot的相关细节内容。在这里,您可以了解你将要使用和定制的主要功能。如果您还没有做好准备,您可能需要阅读 第II部分、入门第III部分、使用Spring Boot,以便打下良好基础。

23、 SpringApplication

SpringApplication 类提供了一种通过运行 main() 方法的方便方式来引导Spring应用。许多情况下,您只需要委托静态的 SpringApplication.run 方法:

public static void main(String[] args) {
    SpringApplication.run(MySpringConfiguration.class, args);
}

当您的应用启动时,你应该会看到类似以下的内容:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::   v1.5.4.RELEASE

2013-07-31 00:08:16.117  INFO 56603 --- [           main] o.s.b.s.app.SampleApplication            : Starting SampleApplication v0.1.0 on mycomputer with PID 56603 (/apps/myapp.jar started by pwebb)
2013-07-31 00:08:16.166  INFO 56603 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@6e5a8246: startup date [Wed Jul 31 00:08:16 PDT 2013]; root of context hierarchy
2014-03-04 13:09:54.912  INFO 41370 --- [           main] .t.TomcatEmbeddedServletContainerFactory : Server initialized with port: 8080
2014-03-04 13:09:56.501  INFO 41370 --- [           main] o.s.b.s.app.SampleApplication            : Started SampleApplication in 2.992 seconds (JVM running for 3.658)

默认情况下,将显示 INFO 级别的日志信息,包括启动应用用户的一些相关的启动详细信息。

23.1 启动失败

如果您的应用无法启动,注册了的 FailureAnalyzers 有可能会提供专门的错误信息和解决问题的具体操作。例如,如果您在已经被使用了的 8080 端口上启动了一个web应用,您应该会看到类似以下的内容:

***************************
APPLICATION FAILED TO START
***************************

Description:

Embedded servlet container failed to start. Port 8080 was already in use.

Action:

Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.
[Note] 注意

Spring Boot provides 提供了众多的 FailureAnalyzer 实现,您可以非常容易地添加自己的实现

如果没有失败分析器能够处理异常,您仍然可以显示完整的自动配置报告以便更好地了解出现的问题。为此,您需要启用 debug 属性 或者 开启 DEBUG 日志,针对 org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer 进行调试日志输出。

例如,如果您使用 java -jar 运行应用,可以按如下方式启用 debug 属性:

$ java -jar myproject-0.0.1-SNAPSHOT.jar --debug

23.2 自定义Banner

可以通过在您的classpath中添加一个 banner.txt 文件,或者将 banner.location 设置到此类文件的位置来更改启动时打印的banner。如果文件采用了不一样的编码,你可以设置 banner.charset(默认是 UTF-8)来解决。除了文本文件,您还可以将 banner.gifbanner.jpg 或者 banner.png 图像文件添加到您的classpath中,或者设置一个 banner.image.location 属性。 图像将会被转换成ASCII的表现形式并打印在任何文本banner上方。

您可以在 banner.txt 文件中使用以下占位符:

表 23.1. Banner变量

变量 描述

${application.version}

MANIFEST.MF 中声明的应用版本号。例如,Implementation-Version: 1.0 将被打印为 1.0

${application.formatted-version}

MANIFEST.MF 中声明的应用版本号,格式化之后打印(用括号括起来,以 v 为前缀) 例如 (v1.0)

${spring-boot.version}

您使用的Spring Boot版本。例如 1.5.4.RELEASE

${spring-boot.formatted-version}

你使用的Spring Boot版本格式化之后显示(用括号括起来,以 v 为前缀)。例如 (v1.5.4.RELEASE)

${Ansi.NAME} (or ${AnsiColor.NAME}, ${AnsiBackground.NAME}, ${AnsiStyle.NAME})

其中 NAME 是ANSI转义码的名称。有关详细信息,请参阅 AnsiPropertySource

${application.title}

MANIFEST.MF 中声明的应用标题,例如 Implementation-Title: MyApp 打印为 MyApp


[Tip] 提示

如果要以编程的方式生成banner,可以使用 SpringApplication.setBanner(​) 方法。使用 org.springframework.boot.Banner 接口并实现自己的 printBanner() 方法。

您还可以使用 spring.main.banner-mode 属性来确定是否必须在 System.outconsole)上打印banner,使用配置的logger (log)或者不打印(关闭)。

打印的banner将注册为名为 springBootBanner 的单例bean。

[Note] 注意

YAML 将off 映射为 false,因此如果要禁用 应用程序中的banner,请确保添加了引号。

spring:
    main:
        banner-mode: "off"

23.3 定制 SpringApplication

如果 SpringApplication 默认值不符合您的想法,您可以创建本地实例并进行自定义。例如:

public static void main(String[] args) {
    SpringApplication app = new SpringApplication(MySpringConfiguration.class);
    app.setBannerMode(Banner.Mode.OFF);
    app.run(args);
}
[Note] 注意

传递给 SpringApplication 的构造参数是spring bean的配置源。大多情况下是引用 @Configuration 类,但也可以引用 XML 配置或者被扫描的包。

也可以使用 application.properties 文件配置 SpringApplication。有关详细信息,请参见 第 24章 外部配置

有关配置选项的完整列表,请参阅 SpringApplication Javadoc

23.4 链式构建器 API

如果您需要构建一个 ApplicationContext 层次结构(具有父/子关系的上下文),或者如果您只想使用链式构建器API,可以使用 SpringApplicationBuilder

SpringApplicationBuilder 允许您链接多个方法调用,包括允许您创建具有层次结构的 / 方法。

例如:

new SpringApplicationBuilder()
        .sources(Parent.class)
        .child(Application.class)
        .bannerMode(Banner.Mode.OFF)
        .run(args);
[Note] 注意

创建 ApplicationContext 层次时有一些限制,例如Web组件 必须 包含在子上下文中, 并且相同的 Environment 将作用于父子上下文。有关详细信息,请参阅 SpringApplicationBuilder Javadoc

23.5 应用程序事件与监听器

除了常见的Spring Framework事件,比如 ContextRefreshedEventSpringApplication 还会发送一些其他应用程序事件。

[Note] 注意

在创建 ApplicationContext 之前,实际上触发了一些事件,因此您不能在 @Bean 上注册一个监听器。您可以通过 SpringApplication.addListeners(​) 或者 SpringApplicationBuilder.listeners(​) 方法注册它们。

如果您希望自动注册这些监听器,无论应用创建的方式如何,您都可以将 META-INF/spring.factories 文件添加到项目中,并使用 org.springframework.context.ApplicationListener 键引用您的监听器。

org.springframework.context.ApplicationListener=com.example.project.MyListener

当您运行应用时,应用程序事件将按照以下顺序发送:

  1. 在开始运行时,ApplicationStartingEvent 在监听器注册和初始化之后被发送。
  2. ApplicationEnvironmentPreparedEvent 发现 Environment 被上下文使用时,将被发送,但是在上下文被创建之前。
  3. ApplicationPreparedEvent 在启动刷新之前,bean定义被加载之后被发送。
  4. 在刷新并且处理了用于指示应用准备处理请求的相关回调之后,ApplicationReadyEvent 将被发送。
  5. 如果启动时发生异常,ApplicationFailedEvent 将被发送。
[Tip] 提示

你可能将不会经常使用应用程序事件,但这有利于您知道它们的存在。在内部,Spring Boot 使用事件来处理各种任务。

23.6 Web环境

SpringApplication 将尝试为你创建正确类型的 ApplicationContext。默认情况下,将使用 AnnotationConfigApplicationContext 或者 AnnotationConfigEmbeddedWebApplicationContext,具体取决于您是否在开发 web 应用。

用于确定“web环境”的算法非常简单(基于几个类的存在)。如果需要覆盖默认值,可以使用 setWebEnvironment(boolean webEnvironment)

也可以通过调用 setApplicationContextClass(​) 完全控制 ApplicationContext 的类型。

[Tip] 提示

在进行 Junit 测试时使用到 SpringApplication,通常需要调用 setWebEnvironment(false)

23.7 访问应用程序参数

如果您需要访问传递给 SpringApplication.run(​) 的应用程序参数,可以注入 org.springframework.boot.ApplicationArguments bean。ApplicationArguments 接口提供了访问原始 String[] 参数以及解析 可选非可选 参数的能力:

import org.springframework.boot.*
import org.springframework.beans.factory.annotation.*
import org.springframework.stereotype.*

@Component
public class MyBean {

    @Autowired
    public MyBean(ApplicationArguments args) {
        boolean debug = args.containsOption("debug");
        List<String> files = args.getNonOptionArgs();
        // if run with "--debug logfile.txt" debug=true, files=["logfile.txt"]
    }

}
[Tip] 提示

Spring Boot 还向 Spring Environment 注册了一个 CommandLinePropertySource。这允许您可以使用 @Value 注解注入单个应用参数。

23.8 使用 ApplicationRunner 或者 CommandLineRunner

如果您想在 SpringApplication 启动瞬间运行一些特定的代码,可以实现 ApplicationRunner 或者 CommandLineRunner 接口。这两口接口的工作方式是一样的,都提供了一个单独的 run 方法, 它将在 SpringApplication.run(​) 完成之前调用。

CommandLineRunner 接口提供了访问应用程序字符串数组形式的参数能力,而 ApplicationRunner 则使用了上述的 ApplicationArguments 接口。

import org.springframework.boot.*
import org.springframework.stereotype.*

@Component
public class MyBean implements CommandLineRunner {

    public void run(String... args) {
        // Do something...
    }

}

如果您定义了多个 CommandLineRunner 或者 ApplicationRunner beans,可以额外实现 org.springframework.core.Ordered 接口,也可以使用 org.springframework.core.annotation.Order 注解解决,因为这些bean必须按特定的顺序调用。

23.9 退出应用程序

每个 SpringApplication 将注册一个 JVM 关闭钩子,以确保 ApplicationContext 在退出时正常关闭。您可以使用所有标准的 Spring 生命周期回调(比如 DisposableBean 接口,或者 @PreDestroy 注解)。

另外,如果希望 bean 在应用程序结束时返回特定的退出码,那么 bena 可以实现 org.springframework.boot.ExitCodeGenerator 接口。

23.10 管理功能

可以通过指定 spring.application.admin.enabled 属性来为应用启用管理相关的功能。这将会在 MBeanServer 平台上暴露 SpringApplicationAdminMXBean。您可以使用此功能来远程管理您的 Spring Boot 应用。这对于任何服务包装器的实现也是非常有用的。

[Tip] 提示

如果您想知道应用程序在哪一个 HTTP 端口上运行,请使用 local.server.port 键获取该属性。

[Note] 注意

启用此功能时请小心,因为 MBean 暴露了关闭应用程序的方法。

24. 外部配置

Spring Boot 允许您在外部进行配置,以便您可以在不同环境中使用相同的应用代码。你可以使用 properties 文件、YAML 文件、环境变量或者命令行参数来外部化配置。可以使用 @Value 注解将属性值直接注入到您的 bean 中,该注解可通过 Spring 的 Environment 访问,或者通过 @ConfigurationProperties 绑定到结构化对象

Spring Boot 使用非常特殊的 PropertySource 指令,旨在允许合理地覆盖默认值。属性将按一下顺序考虑:

  1. 在您的主目录(~/.spring-boot-devtools.properties 当 devtools 被激活)的 Devtools 全局设置 properties
  2. 在您的测试中使用到的 @TestPropertySource 注解。
  3. 在测试中使用到的 @SpringBootTest#properties 注解属性。
  4. 命令行参数。
  5. 来自 SPRING_APPLICATION_JSON 的 properties(嵌入在环境变量或者 system property 中的内联 JSON)。
  6. ServletConfig 初始化参数。
  7. ServletContext 初始化参数。
  8. 来自 java:comp/env 的 JNDI 属性。
  9. Java System properties (System.getProperties())。
  10. 操作系统环境变量。
  11. 一个只有 random.* properties 的 RandomValuePropertySource
  12. 在打包好的 jar 之外的特定的 profile 应用 propertiesapplication-{profile}.properties 和 YAML 变量)。
  13. 在打包好的 jar 内的 特定的 profile 应用 propertiesapplication-{profile}.properties 和 YAML 变量)。
  14. 在打包的 jar 外的应用 properties(application.properties 和 YAML 变量。
  15. 在打包的 jar 内的应用 properties(application.properties 和 YAML 变量)。
  16. @Configuration 上的 @PropertySource 注解。
  17. 默认 properties(特定使用 SpringApplication.setDefaultProperties)。

举个例子,假设您开发一个使用 name 属性的 @Component

import org.springframework.stereotype.*
import org.springframework.beans.factory.annotation.*

@Component
public class MyBean {

    @Value("${name}")
    private String name;

    // ...

}

在您的应用的 classpath 中(比如在 jar 中),您可以有一个 application.properties,它为 name 提供了一个合理的默认属性值。在新环境中运行时,您可以在 jar 外面提供一个 application.properties 来覆盖 name;对于一次性测试,您可以使用特定的命令行开关启动(比如 java -jar app.jar --name="Spring")。

[Tip] 提示

SPRING_APPLICATION_JSON properties 可以在命令行中提供一个环境变量。比如在 UN*X shell 中:

$ SPRING_APPLICATION_JSON='{"foo":{"bar":"spam"}}' java -jar myapp.jar

在此示例中,你将在 Spring Environment 中使用 foo.bar=spam。您也可以在系统变量中将 JSON 作为 spring.application.json 提供:

$ java -Dspring.application.json='{"foo":"bar"}' -jar myapp.jar

或者命令行参数:

$ java -jar myapp.jar --spring.application.json='{"foo":"bar"}'

或者一个 JNDI 变量 java:comp/env/spring.application.json

24.1 配置随机值

RandomValuePropertySource 可用于注入随机值(比如在保密场景或者测试用例中)。它可以产生 integer、long、uuid 和 string。例如

my.secret=${random.value}
my.number=${random.int}
my.bignumber=${random.long}
my.uuid=${random.uuid}
my.number.less.than.ten=${random.int(10)}
my.number.in.range=${random.int[1024,65536]}

random.int* 语法是 OPEN value (,max) CLOSEOPEN,CLOSE 可以使任意字符,value,max 为整型。如果提供了 maxvalue 为最小值,max 为最大值。

24.2 Accessing command line properties

By default SpringApplication will convert any command line option arguments (starting with �--�, e.g. --server.port=9000) to a property and add it to the Spring Environment. As mentioned above, command line properties always take precedence over other property sources.

If you don�t want command line properties to be added to the Environment you can disable them using SpringApplication.setAddCommandLineProperties(false).

24.3 Application property files

SpringApplication will load properties from application.properties files in the following locations and add them to the Spring Environment:

  1. A /config subdirectory of the current directory.
  2. The current directory
  3. A classpath /config package
  4. The classpath root

The list is ordered by precedence (properties defined in locations higher in the list override those defined in lower locations).

[Note] Note

You can also use YAML ('.yml') files as an alternative to '.properties'.

If you don�t like application.properties as the configuration file name you can switch to another by specifying a spring.config.name environment property. You can also refer to an explicit location using the spring.config.location environment property (comma-separated list of directory locations, or file paths).

$ java -jar myproject.jar --spring.config.name=myproject

or

$ java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
[Warning] Warning

spring.config.name and spring.config.location are used very early to determine which files have to be loaded so they have to be defined as an environment property (typically OS env, system property or command line argument).

If spring.config.location contains directories (as opposed to files) they should end in / (and will be appended with the names generated from spring.config.name before being loaded, including profile-specific file names). Files specified in spring.config.location are used as-is, with no support for profile-specific variants, and will be overridden by any profile-specific properties.

The default search path classpath:,classpath:/config,file:,file:config/ is always used, irrespective of the value of spring.config.location. This search path is ordered from lowest to highest precedence (file:config/ wins). If you do specify your own locations, they take precedence over all of the default locations and use the same lowest to highest precedence ordering. In that way you can set up default values for your application in application.properties (or whatever other basename you choose with spring.config.name) and override it at runtime with a different file, keeping the defaults.

[Note] Note

If you use environment variables rather than system properties, most operating systems disallow period-separated key names, but you can use underscores instead (e.g. SPRING_CONFIG_NAME instead of spring.config.name).

[Note] Note

If you are running in a container then JNDI properties (in java:comp/env) or servlet context initialization parameters can be used instead of, or as well as, environment variables or system properties.

24.4 Profile-specific properties

In addition to application.properties files, profile-specific properties can also be defined using the naming convention application-{profile}.properties. The Environment has a set of default profiles (by default [default]) which are used if no active profiles are set (i.e. if no profiles are explicitly activated then properties from application-default.properties are loaded).

Profile-specific properties are loaded from the same locations as standard application.properties, with profile-specific files always overriding the non-specific ones irrespective of whether the profile-specific files are inside or outside your packaged jar.

If several profiles are specified, a last wins strategy applies. For example, profiles specified by the spring.profiles.active property are added after those configured via the SpringApplication API and therefore take precedence.

[Note] Note

If you have specified any files in spring.config.location, profile-specific variants of those files will not be considered. Use directories in spring.config.location if you also want to also use profile-specific properties.

24.5 Placeholders in properties

The values in application.properties are filtered through the existing Environment when they are used so you can refer back to previously defined values (e.g. from System properties).

app.name=MyApp
app.description=${app.name} is a Spring Boot application
[Tip] Tip

You can also use this technique to create �short� variants of existing Spring Boot properties. See the Section 72.4, �Use �short� command line arguments� how-to for details.

24.6 Using YAML instead of Properties

YAML is a superset of JSON, and as such is a very convenient format for specifying hierarchical configuration data. The SpringApplication class will automatically support YAML as an alternative to properties whenever you have the SnakeYAML library on your classpath.

[Note] Note

If you use �Starters� SnakeYAML will be automatically provided via spring-boot-starter.

24.6.1 Loading YAML

Spring Framework provides two convenient classes that can be used to load YAML documents. The YamlPropertiesFactoryBean will load YAML as Properties and the YamlMapFactoryBean will load YAML as a Map.

For example, the following YAML document:

environments:
    dev:
        url: http://dev.bar.com
        name: Developer Setup
    prod:
        url: http://foo.bar.com
        name: My Cool App

Would be transformed into these properties:

environments.dev.url=http://dev.bar.com
environments.dev.name=Developer Setup
environments.prod.url=http://foo.bar.com
environments.prod.name=My Cool App

YAML lists are represented as property keys with [index] dereferencers, for example this YAML:

my:
   servers:
       - dev.bar.com
       - foo.bar.com

Would be transformed into these properties:

my.servers[0]=dev.bar.com
my.servers[1]=foo.bar.com

To bind to properties like that using the Spring DataBinder utilities (which is what @ConfigurationProperties does) you need to have a property in the target bean of type java.util.List (or Set) and you either need to provide a setter, or initialize it with a mutable value, e.g. this will bind to the properties above

@ConfigurationProperties(prefix="my")
public class Config {

    private List<String> servers = new ArrayList<String>();

    public List<String> getServers() {
        return this.servers;
    }
}
[Note] Note

Extra care is required when configuring lists that way as overriding will not work as you would expect. In the example above, when my.servers is redefined in several places, the individual elements are targeted for override, not the list. To make sure that a PropertySource with higher precedence can override the list, you need to define it as a single property:

my:
   servers: dev.bar.com,foo.bar.com

24.6.2 Exposing YAML as properties in the Spring Environment

The YamlPropertySourceLoader class can be used to expose YAML as a PropertySource in the Spring Environment. This allows you to use the familiar @Value annotation with placeholders syntax to access YAML properties.

24.6.3 Multi-profile YAML documents

You can specify multiple profile-specific YAML documents in a single file by using a spring.profiles key to indicate when the document applies. For example:

server:
    address: 192.168.1.100
---
spring:
    profiles: development
server:
    address: 127.0.0.1
---
spring:
    profiles: production
server:
    address: 192.168.1.120

In the example above, the server.address property will be 127.0.0.1 if the development profile is active. If the development and production profiles are not enabled, then the value for the property will be 192.168.1.100.

The default profiles are activated if none are explicitly active when the application context starts. So in this YAML we set a value for security.user.password that is only available in the "default" profile:

server:
  port: 8000
---
spring:
  profiles: default
security:
  user:
    password: weak

whereas in this example, the password is always set because it isn�t attached to any profile, and it would have to be explicitly reset in all other profiles as necessary:

server:
  port: 8000
security:
  user:
    password: weak

Spring profiles designated using the "spring.profiles" element may optionally be negated using the ! character. If both negated and non-negated profiles are specified for a single document, at least one non-negated profile must match and no negated profiles may match.

24.6.4 YAML shortcomings

YAML files can�t be loaded via the @PropertySource annotation. So in the case that you need to load values that way, you need to use a properties file.

24.6.5 Merging YAML lists

As we have seen above, any YAML content is ultimately transformed to properties. That process may be counter intuitive when overriding �list� properties via a profile.

For example, assume a MyPojo object with name and description attributes that are null by default. Let�s expose a list of MyPojo from FooProperties:

@ConfigurationProperties("foo")
public class FooProperties {

    private final List<MyPojo> list = new ArrayList<>();

    public List<MyPojo> getList() {
        return this.list;
    }

}

Consider the following configuration:

foo:
  list:
    - name: my name
      description: my description
---
spring:
  profiles: dev
foo:
  list:
    - name: my another name

If the dev profile isn�t active, FooProperties.list will contain one MyPojo entry as defined above. If the dev profile is enabled however, the list will still only contain one entry (with name �my another name� and description null). This configuration will not add a second MyPojo instance to the list, and it won�t merge the items.

When a collection is specified in multiple profiles, the one with highest priority is used (and only that one):

foo:
              list:
                - name: my name
                  description: my description
                - name: another name
                  description: another description
            ---
            spring:
              profiles: dev
            foo:
              list:
                 - name: my another name

In the example above, considering that the dev profile is active, FooProperties.list will contain one MyPojo entry (with name �my another name� and description null).

24.7 Type-safe Configuration Properties

Using the @Value("${property}") annotation to inject configuration properties can sometimes be cumbersome, especially if you are working with multiple properties or your data is hierarchical in nature. Spring Boot provides an alternative method of working with properties that allows strongly typed beans to govern and validate the configuration of your application.

package com.example;

import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties("foo")
public class FooProperties {

    private boolean enabled;

    private InetAddress remoteAddress;

    private final Security security = new Security();

    public boolean isEnabled() { ... }

    public void setEnabled(boolean enabled) { ... }

    public InetAddress getRemoteAddress() { ... }

    public void setRemoteAddress(InetAddress remoteAddress) { ... }

    public Security getSecurity() { ... }

    public static class Security {

        private String username;

        private String password;

        private List<String> roles = new ArrayList<>(Collections.singleton("USER"));

        public String getUsername() { ... }

        public void setUsername(String username) { ... }

        public String getPassword() { ... }

        public void setPassword(String password) { ... }

        public List<String> getRoles() { ... }

        public void setRoles(List<String> roles) { ... }

    }
}

The POJO above defines the following properties:

  • foo.enabled, false by default
  • foo.remote-address, with a type that can be coerced from String
  • foo.security.username, with a nested "security" whose name is determined by the name of the property. In particular the return type is not used at all there and could have been SecurityProperties
  • foo.security.password
  • foo.security.roles, with a collection of String
[Note] Note

Getters and setters are usually mandatory, since binding is via standard Java Beans property descriptors, just like in Spring MVC. There are cases where a setter may be omitted:

  • Maps, as long as they are initialized, need a getter but not necessarily a setter since they can be mutated by the binder.
  • Collections and arrays can be either accessed via an index (typically with YAML) or using a single comma-separated value (properties). In the latter case, a setter is mandatory. We recommend to always add a setter for such types. If you initialize a collection, make sure it is not immutable (as in the example above)
  • If nested POJO properties are initialized (like the Security field in the example above), a setter is not required. If you want the binder to create the instance on-the-fly using its default constructor, you will need a setter.

Some people use Project Lombok to add getters and setters automatically. Make sure that Lombok doesn�t generate any particular constructor for such type as it will be used automatically by the container to instantiate the object.

You also need to list the properties classes to register in the @EnableConfigurationProperties annotation:

@Configuration
@EnableConfigurationProperties(FooProperties.class)
public class MyConfiguration {
}
[Note] Note

When @ConfigurationProperties bean is registered that way, the bean will have a conventional name: <prefix>-<fqn>, where <prefix> is the environment key prefix specified in the @ConfigurationProperties annotation and <fqn> the fully qualified name of the bean. If the annotation does not provide any prefix, only the fully qualified name of the bean is used.

The bean name in the example above will be foo-com.example.FooProperties.

Even if the configuration above will create a regular bean for FooProperties, we recommend that @ConfigurationProperties only deal with the environment and in particular does not inject other beans from the context. Having said that, The @EnableConfigurationProperties annotation is also automatically applied to your project so that any existing bean annotated with @ConfigurationProperties will be configured from the Environment. You could shortcut MyConfiguration above by making sure FooProperties is a already a bean:

@Component
@ConfigurationProperties(prefix="foo")
public class FooProperties {

    // ... see above

}

This style of configuration works particularly well with the SpringApplication external YAML configuration:

# application.yml

foo:
    remote-address: 192.168.1.1
    security:
        username: foo
        roles:
          - USER
          - ADMIN

# additional configuration as required

To work with @ConfigurationProperties beans you can just inject them in the same way as any other bean.

@Service
public class MyService {

    private final FooProperties properties;

    @Autowired
    public MyService(FooProperties properties) {
        this.properties = properties;
    }

     //...

    @PostConstruct
    public void openConnection() {
        Server server = new Server(this.properties.getRemoteAddress());
        // ...
    }

}
[Tip] Tip

Using @ConfigurationProperties also allows you to generate meta-data files that can be used by IDEs to offer auto-completion for your own keys, see the Appendix B, Configuration meta-data appendix for details.

24.7.1 Third-party configuration

As well as using @ConfigurationProperties to annotate a class, you can also use it on public @Bean methods. This can be particularly useful when you want to bind properties to third-party components that are outside of your control.

To configure a bean from the Environment properties, add @ConfigurationProperties to its bean registration:

@ConfigurationProperties(prefix = "bar")
@Bean
public BarComponent barComponent() {
    ...
}

Any property defined with the bar prefix will be mapped onto that BarComponent bean in a similar manner as the FooProperties example above.

24.7.2 Relaxed binding

Spring Boot uses some relaxed rules for binding Environment properties to @ConfigurationProperties beans, so there doesn�t need to be an exact match between the Environment property name and the bean property name. Common examples where this is useful include dashed separated (e.g. context-path binds to contextPath), and capitalized (e.g. PORT binds to port) environment properties.

For example, given the following @ConfigurationProperties class:

@ConfigurationProperties(prefix="person")
public class OwnerProperties {

    private String firstName;

    public String getFirstName() {
        return this.firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

}

The following properties names can all be used:

Table 24.1. relaxed binding

Property Note

person.firstName

Standard camel case syntax.

person.first-name

Dashed notation, recommended for use in .properties and .yml files.

person.first_name

Underscore notation, alternative format for use in .properties and .yml files.

PERSON_FIRST_NAME

Upper case format. Recommended when using a system environment variables.


24.7.3 Properties conversion

Spring will attempt to coerce the external application properties to the right type when it binds to the @ConfigurationProperties beans. If you need custom type conversion you can provide a ConversionService bean (with bean id conversionService) or custom property editors (via a CustomEditorConfigurer bean) or custom Converters (with bean definitions annotated as @ConfigurationPropertiesBinding).

[Note] Note

As this bean is requested very early during the application lifecycle, make sure to limit the dependencies that your ConversionService is using. Typically, any dependency that you require may not be fully initialized at creation time. You may want to rename your custom ConversionService if it�s not required for configuration keys coercion and only rely on custom converters qualified with @ConfigurationPropertiesBinding.

24.7.4 @ConfigurationProperties Validation

Spring Boot will attempt to validate @ConfigurationProperties classes whenever they are annotated with Spring�s @Validated annotation. You can use JSR-303 javax.validation constraint annotations directly on your configuration class. Simply ensure that a compliant JSR-303 implementation is on your classpath, then add constraint annotations to your fields:

@ConfigurationProperties(prefix="foo")
@Validated
public class FooProperties {

    @NotNull
    private InetAddress remoteAddress;

    // ... getters and setters

}

In order to validate values of nested properties, you must annotate the associated field as @Valid to trigger its validation. For example, building upon the above FooProperties example:

@ConfigurationProperties(prefix="connection")
@Validated
public class FooProperties {

    @NotNull
    private InetAddress remoteAddress;

    @Valid
    private final Security security = new Security();

    // ... getters and setters

    public static class Security {

        @NotEmpty
        public String username;

        // ... getters and setters

    }

}

You can also add a custom Spring Validator by creating a bean definition called configurationPropertiesValidator. The @Bean method should be declared static. The configuration properties validator is created very early in the application�s lifecycle and declaring the @Bean method as static allows the bean to be created without having to instantiate the @Configuration class. This avoids any problems that may be caused by early instantiation. There is a property validation sample so you can see how to set things up.

[Tip] Tip

The spring-boot-actuator module includes an endpoint that exposes all @ConfigurationProperties beans. Simply point your web browser to /configprops or use the equivalent JMX endpoint. See the Production ready features. section for details.

24.7.5 @ConfigurationProperties vs. @Value

@Value is a core container feature and it does not provide the same features as type-safe Configuration Properties. The table below summarizes the features that are supported by @ConfigurationProperties and @Value:

Feature @ConfigurationProperties @Value

Relaxed binding

Yes

No

Meta-data support

Yes

No

SpEL evaluation

No

Yes

If you define a set of configuration keys for your own components, we recommend you to group them in a POJO annotated with @ConfigurationProperties. Please also be aware that since @Value does not support relaxed binding, it isn�t a great candidate if you need to provide the value using environment variables.

Finally, while you can write a SpEL expression in @Value, such expressions are not processed from Application property files.

25. Profiles

Spring Profiles provide a way to segregate parts of your application configuration and make it only available in certain environments. Any @Component or @Configuration can be marked with @Profile to limit when it is loaded:

@Configuration
@Profile("production")
public class ProductionConfiguration {

    // ...

}

In the normal Spring way, you can use a spring.profiles.active Environment property to specify which profiles are active. You can specify the property in any of the usual ways, for example you could include it in your application.properties:

spring.profiles.active=dev,hsqldb

or specify on the command line using the switch --spring.profiles.active=dev,hsqldb.

25.1 Adding active profiles

The spring.profiles.active property follows the same ordering rules as other properties, the highest PropertySource will win. This means that you can specify active profiles in application.properties then replace them using the command line switch.

Sometimes it is useful to have profile-specific properties that add to the active profiles rather than replace them. The spring.profiles.include property can be used to unconditionally add active profiles. The SpringApplication entry point also has a Java API for setting additional profiles (i.e. on top of those activated by the spring.profiles.active property): see the setAdditionalProfiles() method.

For example, when an application with following properties is run using the switch --spring.profiles.active=prod the proddb and prodmq profiles will also be activated:

---
my.property: fromyamlfile
---
spring.profiles: prod
spring.profiles.include:
  - proddb
  - prodmq
[Note] Note

Remember that the spring.profiles property can be defined in a YAML document to determine when this particular document is included in the configuration. See Section 72.7, �Change configuration depending on the environment� for more details.

25.2 Programmatically setting profiles

You can programmatically set active profiles by calling SpringApplication.setAdditionalProfiles(�​) before your application runs. It is also possible to activate profiles using Spring�s ConfigurableEnvironment interface.

25.3 Profile-specific configuration files

Profile-specific variants of both application.properties (or application.yml) and files referenced via @ConfigurationProperties are considered as files are loaded. See Section 24.4, �Profile-specific properties� for details.

26. Logging

Spring Boot uses Commons Logging for all internal logging, but leaves the underlying log implementation open. Default configurations are provided for Java Util Logging, Log4J2 and Logback. In each case loggers are pre-configured to use console output with optional file output also available.

By default, If you use the �Starters�, Logback will be used for logging. Appropriate Logback routing is also included to ensure that dependent libraries that use Java Util Logging, Commons Logging, Log4J or SLF4J will all work correctly.

[Tip] Tip

There are a lot of logging frameworks available for Java. Don�t worry if the above list seems confusing. Generally you won�t need to change your logging dependencies and the Spring Boot defaults will work just fine.

26.1 Log format

The default log output from Spring Boot looks like this:

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: [/*]

The following items are output:

  • Date and Time � Millisecond precision and easily sortable.
  • Log Level � ERROR, WARN, INFO, DEBUG or TRACE.
  • Process ID.
  • A --- separator to distinguish the start of actual log messages.
  • Thread name � Enclosed in square brackets (may be truncated for console output).
  • Logger name � This is usually the source class name (often abbreviated).
  • The log message.
[Note] Note

Logback does not have a FATAL level (it is mapped to ERROR)

26.2 Console output

The default log configuration will echo messages to the console as they are written. By default ERROR, WARN and INFO level messages are logged. You can also enable a �debug� mode by starting your application with a --debug flag.

$ java -jar myapp.jar --debug
[Note] Note

you can also specify debug=true in your application.properties.

When the debug mode is enabled, a selection of core loggers (embedded container, Hibernate and Spring Boot) are configured to output more information. Enabling the debug mode does not configure your application to log all messages with DEBUG level.

Alternatively, you can enable a �trace� mode by starting your application with a --trace flag (or trace=true in your application.properties). This will enable trace logging for a selection of core loggers (embedded container, Hibernate schema generation and the whole Spring portfolio).

26.2.1 Color-coded output

If your terminal supports ANSI, color output will be used to aid readability. You can set spring.output.ansi.enabled to a supported value to override the auto detection.

Color coding is configured using the %clr conversion word. In its simplest form the converter will color the output according to the log level, for example:

%clr(%5p)

The mapping of log level to a color is as follows:

Level Color

FATAL

Red

ERROR

Red

WARN

Yellow

INFO

Green

DEBUG

Green

TRACE

Green

Alternatively, you can specify the color or style that should be used by providing it as an option to the conversion. For example, to make the text yellow:

%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){yellow}

The following colors and styles are supported:

  • blue
  • cyan
  • faint
  • green
  • magenta
  • red
  • yellow

26.3 File output

By default, Spring Boot will only log to the console and will not write log files. If you want to write log files in addition to the console output you need to set a logging.file or logging.path property (for example in your application.properties).

The following table shows how the logging.* properties can be used together:

Table 26.1. Logging properties

logging.file logging.path Example Description

(none)

(none)

 

Console only logging.

Specific file

(none)

my.log

Writes to the specified log file. Names can be an exact location or relative to the current directory.

(none)

Specific directory

/var/log

Writes spring.log to the specified directory. Names can be an exact location or relative to the current directory.


Log files will rotate when they reach 10 MB and as with console output, ERROR, WARN and INFO level messages are logged by default.

[Note] Note

The logging system is initialized early in the application lifecycle and as such logging properties will not be found in property files loaded via @PropertySource annotations.

[Tip] Tip

Logging properties are independent of the actual logging infrastructure. As a result, specific configuration keys (such as logback.configurationFile for Logback) are not managed by spring Boot.

26.4 Log Levels

All the supported logging systems can have the logger levels set in the Spring Environment (so for example in application.properties) using �logging.level.*=LEVEL� where �LEVEL� is one of TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF. The root logger can be configured using logging.level.root. Example application.properties:

logging.level.root=WARN
            logging.level.org.springframework.web=DEBUG
            logging.level.org.hibernate=ERROR
[Note] Note

By default Spring Boot remaps Thymeleaf INFO messages so that they are logged at DEBUG level. This helps to reduce noise in the standard log output. See LevelRemappingAppender for details of how you can apply remapping in your own configuration.

26.5 Custom log configuration

The various logging systems can be activated by including the appropriate libraries on the classpath, and further customized by providing a suitable configuration file in the root of the classpath, or in a location specified by the Spring Environment property logging.config.

You can force Spring Boot to use a particular logging system using the org.springframework.boot.logging.LoggingSystem system property. The value should be the fully-qualified class name of a LoggingSystem implementation. You can also disable Spring Boot�s logging configuration entirely by using a value of none.

[Note] Note

Since logging is initialized before the ApplicationContext is created, it isn�t possible to control logging from @PropertySources in Spring @Configuration files. System properties and the conventional Spring Boot external configuration files work just fine.)

Depending on your logging system, the following files will be loaded:

Logging System Customization

Logback

logback-spring.xml, logback-spring.groovy, logback.xml or logback.groovy

Log4j2

log4j2-spring.xml or log4j2.xml

JDK (Java Util Logging)

logging.properties

[Note] Note

When possible we recommend that you use the -spring variants for your logging configuration (for example logback-spring.xml rather than logback.xml). If you use standard configuration locations, Spring cannot completely control log initialization.

[Warning] Warning

There are known classloading issues with Java Util Logging that cause problems when running from an �executable jar�. We recommend that you avoid it if at all possible.

To help with the customization some other properties are transferred from the Spring Environment to System properties:

Spring Environment System Property Comments

logging.exception-conversion-word

LOG_EXCEPTION_CONVERSION_WORD

The conversion word that�s used when logging exceptions.

logging.file

LOG_FILE

Used in default log configuration if defined.

logging.path

LOG_PATH

Used in default log configuration if defined.

logging.pattern.console

CONSOLE_LOG_PATTERN

The log pattern to use on the console (stdout). (Only supported with the default logback setup.)

logging.pattern.file

FILE_LOG_PATTERN

The log pattern to use in a file (if LOG_FILE enabled). (Only supported with the default logback setup.)

logging.pattern.level

LOG_LEVEL_PATTERN

The format to use to render the log level (default %5p). (Only supported with the default logback setup.)

PID

PID

The current process ID (discovered if possible and when not already defined as an OS environment variable).

All the logging systems supported can consult System properties when parsing their configuration files. See the default configurations in spring-boot.jar for examples.

[Tip] Tip

If you want to use a placeholder in a logging property, you should use Spring Boot�s syntax and not the syntax of the underlying framework. Notably, if you�re using Logback, you should use : as the delimiter between a property name and its default value and not :-.

[Tip] Tip

You can add MDC and other ad-hoc content to log lines by overriding only the LOG_LEVEL_PATTERN (or logging.pattern.level with Logback). For example, if you use logging.pattern.level=user:%X{user} %5p then the default log format will contain an MDC entry for "user" if it exists, e.g.

2015-09-30 12:30:04.031 user:juergen INFO 22174 --- [  nio-8080-exec-0] demo.Controller
Handling authenticated request

26.6 Logback extensions

Spring Boot includes a number of extensions to Logback which can help with advanced configuration. You can use these extensions in your logback-spring.xml configuration file.

[Note] Note

You cannot use extensions in the standard logback.xml configuration file since it�s loaded too early. You need to either use logback-spring.xml or define a logging.config property.

[Warning] Warning

The extensions cannot be used with Logback�s configuration scanning. If you attempt to do so, making changes to the configuration file will result in an error similar to one of the following being logged:

ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProperty], current ElementPath is [[configuration][springProperty]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProfile], current ElementPath is [[configuration][springProfile]]

26.6.1 Profile-specific configuration

The <springProfile> tag allows you to optionally include or exclude sections of configuration based on the active Spring profiles. Profile sections are supported anywhere within the <configuration> element. Use the name attribute to specify which profile accepts the configuration. Multiple profiles can be specified using a comma-separated list.

<springProfile name="staging">
    <!-- configuration to be enabled when the "staging" profile is active -->
</springProfile>

<springProfile name="dev, staging">
    <!-- configuration to be enabled when the "dev" or "staging" profiles are active -->
</springProfile>

<springProfile name="!production">
    <!-- configuration to be enabled when the "production" profile is not active -->
</springProfile>

26.6.2 Environment properties

The <springProperty> tag allows you to surface properties from the Spring Environment for use within Logback. This can be useful if you want to access values from your application.properties file in your logback configuration. The tag works in a similar way to Logback�s standard <property> tag, but rather than specifying a direct value you specify the source of the property (from the Environment). You can use the scope attribute if you need to store the property somewhere other than in local scope. If you need a fallback value in case the property is not set in the Environment, you can use the defaultValue attribute.

<springProperty scope="context" name="fluentHost" source="myapp.fluentd.host"
        defaultValue="localhost"/>
<appender name="FLUENT" class="ch.qos.logback.more.appenders.DataFluentAppender">
    <remoteHost>${fluentHost}</remoteHost>
    ...
</appender>
[Tip] Tip

The RelaxedPropertyResolver is used to access Environment properties. If specify the source in dashed notation ( my-property-name) all the relaxed variations will be tried (myPropertyName, MY_PROPERTY_NAME etc).

27. 开发 web 应用程序

Spring Boot 非常适合用于开发 web 应用程序。您可以使用嵌入式 Tomcat、Jetty 或者 Undertow 来创建一个自包含(self-contained)的 HTTP 服务器。大多数 web 应用程序使用 spring-boot-starter-web 模块来快速搭建和运行。

如果您尚未开发过 Spring Boot web 应用程序,则可以按照 入门 章节中的 “Hello World!”示例进行操作。

27.1 Spring Web MVC 框架

Spring Web MVC 框架(通常简称“Spring MVC”)是一个富“模型-视图-控制器”的 web 框架。Spring MVC 允许您创建特殊的 @Controller 或者 @RestController bean 来处理传入的 HTTP 请求。控制器中的方法将使用 @RequestMapping 注解来映射到 HTTP。

以下是一个使用 @RestController 来响应 JSON 数据的典型示例:

@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) {
        // ...
    }

}

Spring MVC 是 Spring Framework 核心的一部分,详细信息可参考 参考文档spring.io/guides 还提供了几个 Spring MVC 的指南。

27.1.1 Spring MVC 自动配置

Spring Boot 提供了适用于大多数 Spring MVC 应用的自动配置。

自动配置在 Spring 默认值上添加了以下功能:

  • 包含 ContentNegotiatingViewResolverBeanNameViewResolver bean。
  • 支持静态资源。包括对 WebJar 的支持(见下文)。
  • 自动注册 ConverterGenericConverterFormatter bean。
  • 支持 HttpMessageConverter (见下文)。
  • 自动注册 MessageCodesResolver (见下文)。
  • 支持静态 index.html
  • 支持定制 Favicon (见下文)。
  • 自动使用 ConfigurableWebBindingInitializer bean(见下文)。

如果您像保留 Spring Boot MVC 的功能,并且需要添加其他 MVC 配置 (interceptor、formatter 和视图控制器等),则可以添加您自己的 WebMvcConfigurerAdapter 类型的 @Configuration 类,但 不能使用 @EnableWebMvc。如果想定制 RequestMappingHandlerMappingRequestMappingHandlerAdapter 或者 ExceptionHandlerExceptionResolver 实例,您可以声明一个 WebMvcRegistrationsAdapter 实例来提供这些组件。

如果您想完全掌控 Spring MVC,可以添加您自己的标记了 @EnableWebMvc 注解的 @Configuration

27.1.2 HttpMessageConverter

Spring MVC 使用 HttpMessageConverter 接口来转换 HTTP 的请求和响应。开箱即用功能包含了合理的默认值,比如对象可以自动转换为 JSON (使用 Jackson 库) 或者 XML (优先使用 Jackson XML 扩展,其次为 JAXB)。字符串默认使用 UTF-8 编码。

如果需要添加或者定制转换器(converter),可以使用 Spring Boot 的 HttpMessageConverter 类:

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

@Configuration
public class MyConfiguration {

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

}

上下文中的任何 HttpMessageConverter bean 都将被添加到转换器列表中。您也可以用这种方式来覆盖转换器的默认值。

27.1.3 定制 JSON Serializer 与 Deserializer

如果您使用 Jackson 序列化和反序列化 JSON 数据,可能需要自己编写 JsonSerializerJsonDeserializer 类。定制序列化器的做法通常是通过一个模块来注册 Jackson , 然而 Spring Boot 提供了一个备用的 @JsonComponent 注解,它可以更加容易地直接注册 Spring Beans。

您可以直接在 JsonSerializer 或者 JsonDeserializer 实现中使用 @JsonComponent。您也可以在将序列化器/反序列化器作为内部类的类中使用。例如:

import java.io.*;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import org.springframework.boot.jackson.*;

@JsonComponent
public class Example {

    public static class Serializer extends JsonSerializer<SomeObject> {
        // ...
    }

    public static class Deserializer extends JsonDeserializer<SomeObject> {
        // ...
    }

}

ApplicationContext 中所有的 @JsonComponent bean 将被自动注册到 Jackson 中,由于 @JsonComponent 是使用 @Component 注解标记,所以通常 component-scanning 规则是适用的。

Spring Boot 还提供了 JsonObjectSerializerJsonObjectDeserializer 基类, 它们在序列化对象时为标准的 Jackson 版本提供了有用的替代方法。有关详细信息,请参阅 Javadoc。

27.1.4 MessageCodesResolver

Spring MVC 有一个生成错误码的策略,用于从绑定的错误中渲染错误信息: MessageCodesResolver。如果您设置了 spring.mvc.message-codes-resolver.format 属性 PREFIX_ERROR_CODE 或者 POSTFIX_ERROR_CODE (请参阅 DefaultMessageCodesResolver.Format 中的枚举),Spring Boot 将为你创建一个。

27.1.5 静态内容

默认情况下,Spring Boot 将在 classpath 或者 ServletContext 根目录中从名为 /static (或 /public/resources/META-INF/resources)目录下提供静态内容。它使用了 Spring MVC 的 ResourceHttpRequestHandler,因此您可以通过添加自己的 WebMvcConfigurerAdapter 并重写 addResourceHandlers 方法来修改此行为。

在 stand-alone web 应用中,来自容器的默认 servlet 也是被启用的,并充当后援,Spring 决定不处理它,则从 ServletContext 的根目录提供静态服务。大多情况下,这是不会发生的(除非您修改了默认的 MVC 配置),因为 Spring will 始终能通过 DispatcherServlet 来处理请求。

默认情况下,资源被映射到 /**,但可以通过 spring.mvc.static-path-pattern 调整。例如,将所有资源重定位到 /resources/**,如下实现:

spring.mvc.static-path-pattern=/resources/**

您还可以使用 spring.resources.static-locations (使用一个目录位置列表替换默认值)来制定静态资源的位置。如果这样做,默认欢迎页检验将切换到您的自定义位置下,因此,如果在启动时,在任意一个位置下存在 index.html,它将是应用程序的主页。

除了上上述“标准”的静态资源位置之外,还提供了一个用于 Webjar 内容 的特殊情况。如果它们是以 Webjar 格式打包,任何具有 /webjars/** 的路径的资源都将从 jar 文件中提供。

[Tip] 提示

如果您的应用程序将被打包成 jar,请不要使用 src/main/webapp 目录。虽然此目录是一个通用的标准,但它 适用于 war 打包,如果生成的是一个 jar,它将被绝大多数的构建工具所忽略。

Spring Boot 还支持 Spring MVC 提供的高级资源处理功能,允许使用例如静态资源缓存清除或者 Webjar 的版本无关的 URL。

要使用 Webjar 的版本无关 URL,只需要添加 webjars-locator 依赖。 然后声明您的 Webjar,以 jQuery 为例,如 "/webjars/jquery/dist/jquery.min.js" 将变成 "/webjars/jquery/x.y.z/dist/jquery.min.js",其中 x.y.z 是 Webjar 的版本。

[Note] 注意

如果您正在使用 JBoss,则需要声明 webjars-locator-jboss-vfs 依赖而不是 webjars-locator;否则所有的 Webjar 将被解析成 404

要使用缓存清除功能,以下配置是配置了一个所有的静态资源缓存清除解决方案,从而有效地在 URL 中添加内容哈希,例如 <link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/>

                    spring.resources.chain.strategy.content.enabled=true
                    spring.resources.chain.strategy.content.paths=/**
                
[Note] 注意

资源链接在运行时在模板中被重写,这归功于自动配置 Thymeleaf 和 FreeMarker 的 ResourceUrlEncodingFilter。在使用 JSP 时,应该手动声明此过滤器。其他模板引擎现在不会自动支持,但可以使用定制的模板宏(macro)/助手(helper)和 ResourceUrlProvider

当使用例如 Javascript 模块加载器动态加载资源时,重命名文件是不可选的。这也是为什么其他策略也能受到支持并且可以组合的原因。“fixed”策略将在 URL 中添加一个静态版本字符串,而不是更改文件名:

spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
spring.resources.chain.strategy.fixed.enabled=true
spring.resources.chain.strategy.fixed.paths=/js/lib/
spring.resources.chain.strategy.fixed.version=v12

使用此配置,位于 "/js/lib/" 下的 Javascript 模块将使用固定版本策略 "/v12/js/lib/mymodule.js",而其他资源仍使用 <link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/> 内容。

有关更多支持的选项,请参阅 ResourceProperties

[Tip] 提示

这个功能已经在专门的博客文章和 Spring 框架的 blog post and in Spring Framework�s 参考文档中进行了详细描述。

27.1.6 定制 Favicon

Spring Boot 在配置的静态内容位置和 classpath 中查找 favicon.ico(按顺序)。如果此文件存在,它将被自动用作应用程序的 favicon。

27.1.7 ConfigurableWebBindingInitializer

Spring MVC 使用 WebBindingInitializer 为特定的请求初始化 WebDataBinder。如果您创建了自己的 ConfigurableWebBindingInitializer @Bean,Spring Boot 将自动配置 Spring MVC 以使用它。

27.1.8 模板引擎

除了 REST web 服务,您还可以使用 Spring MVC 来提供动态 HTML 内容。Spring MVC 支持各种模板技术,包括 Thymeleaf、FreeMarker 和 JSP。许多其他模板引擎也有自己的 Spring MVC 集成。

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

[Tip] 提示

如果可能,应避免使用 JSP,当使用了嵌入式 servlet 容器,存在几个 已知限制

当您使用这些模板引擎之一并附带默认配置时,您的模板将从 src/main/resources/templates 自动获取。

[Tip] 提示

IntelliJ IDEA 根据您运行应用程序的方式来对 classpath 进行不同的排序。在 IDE 中通过 main 方法来运行应用程序将导致与使用 Maven 或 Gradle 或来自其打包的 jar 运行引用程序的排序有所不同。 则可能会导致 Spring Boot 找不到 classpath 中的模板。如果您受到此问题的影响,您可以重新排序 IDE 中 classpath 来放置模块的 classes 和 resources。或者, 您可以配置模板前缀以搜索 classpath 中的每一个模板目录: classpath*:/templates/

27.1.9 错误处理

默认情况下,Spring Boot 提供了一个 /error 映射,以用合理的方式来处理所有的错误,并在 servlet 容器中注册为“全局”错误页面,对于机器客户端而言,它将产生 一个包含错误、HTTP 状态和异常消息的 JSON 响应。对于浏览器客户端而言,将是一个 以 HTML 格式呈现相同数据(定制它只需要添加一个解析成“error” 的 View)的“whitelabel” 错误视图。要完全替换默认行为,您可以实现 ErrorController 并注册该类型的 bean 定义,或者简单地添加一个 类型为 ErrorAttributes 的 bean 来使用被替换内容的现有的机制。

[Tip] 提示

BasicErrorController 可以用作定制 ErrorController 的基类。如果您想添加新的内容类型处理程序(默认是专门处理 text/html 并为其他内容提供后备),这点尤其有用。要做到这点,,只需要继承 BasicErrorController 并添加一个 带有 produces 属性的 @RequestMapping 的共有方法,并创建一个类型为您新创建的 bean。

您还可以定义一个 @ControllerAdvice 来定制为特定控制器或/和异常类型返回的 JSON 文档。

@ControllerAdvice(basePackageClasses = FooController.class)
public class FooControllerAdvice extends ResponseEntityExceptionHandler {

    @ExceptionHandler(YourException.class)
    @ResponseBody
    ResponseEntity<?> handleControllerException(HttpServletRequest request, Throwable ex) {
        HttpStatus status = getStatus(request);
        return new ResponseEntity<>(new CustomErrorType(status.value(), ex.getMessage()), status);
    }

    private HttpStatus getStatus(HttpServletRequest request) {
        Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
        if (statusCode == null) {
            return HttpStatus.INTERNAL_SERVER_ERROR;
        }
        return HttpStatus.valueOf(statusCode);
    }

}

以上示例中,如果由 FooController 在同一个包中定义的控制器抛出了 YourException,则将使用 CustomerErrorType 类型的 POJO 的 json 表示形式而不是 ErrorAttributes 表示形式。

定制错误页面

如果要显示给定状态码的自定义 HTML 错误页面,请将文件添加到 /error 文件夹中。错误页面可以是静态 HTML(例如,添加在任意静态资源文件夹下) 或者使用 模板构建。该文件的名称应该是确切的状态码或者一个序列掩码。

例如,要将 404 映射到静态 HTML 文件,您的文件夹结构可以如下:

src/
 +- main/
     +- java/
     |   + <source code>
     +- resources/
         +- public/
             +- error/
             |   +- 404.html
             +- <other public assets>

To map all 5xx errors using a FreeMarker template, you�d have a structure like this:

src/ +- main/ +- java/ | + <source code> +- resources/ +- templates/ +- error/ | +- 5xx.ftl +- <other templates>

对于更复杂的映射,您还可以添加实现了 ErrorViewResolver 接口的 bean。

public class MyErrorViewResolver implements ErrorViewResolver {

    @Override
    public ModelAndView resolveErrorView(HttpServletRequest request,
            HttpStatus status, Map<String, Object> model) {
        // Use the request or status to optionally return a ModelAndView
        return ...
    }

}

您还可以使用常规的 Spring MVC 功能,如 @ExceptionHandler 方法@ControllerAdvice。 之后,ErrorController 将接收任何未处理的异常。

映射 Spring MVC 之外的错误页面

对于不使用 Spring MVC 的应用程序,可以使用 ErrorPageRegistrar 接口来直接注册 ErrorPages。这个抽象部分直接与底层的嵌入式 servlet 容器一起工作,即使您没有 Spring MVC DispatcherServlet

@Bean
public ErrorPageRegistrar errorPageRegistrar(){
    return new MyErrorPageRegistrar();
}

// ...

private static class MyErrorPageRegistrar implements ErrorPageRegistrar {

    @Override
    public void registerErrorPages(ErrorPageRegistry registry) {
        registry.addErrorPages(new ErrorPage(HttpStatus.BAD_REQUEST, "/400"));
    }

}

注:如果您注册了一个最终由 Filter(例如,像一些非 Spring web 框架的,如 Jersey 和 Wicket)过滤路径的 ErrorPage,则必须将 Filter 显式注册为 ERROR dispatcher,例如

@Bean
public FilterRegistrationBean myFilter() {
    FilterRegistrationBean registration = new FilterRegistrationBean();
    registration.setFilter(new MyFilter());
    ...
    registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
    return registration;
}

(默认的 FilterRegistrationBean 不包含 ERROR dispatcher 类型)。

WebSphere Application Server 上的错误处理

当部署到 servlet 容器时,Spring Boot 会使用其错误页面过滤器将具有错误状态的请求转发到相应的错误页面。 如果响应未提交,则请求之呢个转发到正确的正确的错误页面。 默认情况下,WebSphere Application Server 8.0 以及更高版本在成功完成 servlet 的 service 方法后提交响应。您应该通过将 com.ibm.ws.webcontainer.invokeFlushAfterService 设置为 false 来禁用此行为。

27.1.10 Spring HATEOAS

如果您正在开发利用了超媒体的 RESTful API,Spring Boot 可以为 Spring HATEOAS 提供自动配置,适用于大多数应用程序。自动配置取代了使用 @EnableHypermediaSupport 的需要,并注册了一些 bean,以便轻松构建基于超媒体的应用程序,其包括了一个 LinkDiscoverers (用于客户端支持)和一个用于配置将响应正确展示的 ObjectMapperObjectMapper 可以基于 spring.jackson.* properties 或者 Jackson2ObjectMapperBuilder bean 定制(如果存在)。

您可以使用 @EnableHypermediaSupport 控制 Spring HATEOAS 的配置。请注意,这使得上述的 ObjectMapper 定制将被禁用。

27.1.11 CORS 支持

跨域资源共享(Cross-origin resource sharing,CORS)是 大多数浏览器 实现的 W3C 规范,允许您以灵活的啊方式指定何种跨域请求可以被授权,而不是使用一些不太安全和不太强大的方法,如 IFRAME 或者 JSONP。

从 4.2 版本起,Spring MVC 支持 CORS 开箱即用。在您的 Spring Boot 应用程序中使用 @CrossOrigin 注解配置 控制器方法的 CORS。 可以通过使用自定义的 addCorsMappings(CorsRegistry) 方法注册 WebMvcConfigurer bean 来定义 全局 CORS 配置

@Configuration
public class MyConfiguration {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/api/**");
            }
        };
    }
}

27.2 JAX-RS 与 Jersey

如果您喜欢 JAX-RS 编程模型的 REST 端点,您可以使用一个不是 Spring MVC 的实现。如果您在应用程序上下文中注册了一个 @Bean 形式的 Servlet 或者 Filter,那么 Jersey 1.x 和 Apache CXF 即可开箱即用。Jersey 2.x 有部分的本地 Spring 支持,所以我们也在 starter 中提供了其与 Spring Boot 整合的自动配置支持。

要开始使用 Jersey 2.x,只需要将 spring-boot-starter-jersey 作为依赖,然后您需要一个 ResourceConfig 类型的 @Bean,您可以在其中注册所有的端点:

@Component
public class JerseyConfig extends ResourceConfig {

    public JerseyConfig() {
        register(Endpoint.class);
    }

}
[Warning] Warning

Jersey 对于扫描可执行归档文件的支持是相当有限的。例如,当运行可执行的 war 文件时,它无法扫描包中 WEB-INF/classes 下的端点。为了避免此限制,不应该使用 packages 方法,应该使用上述 register 方法来单独注册每一个端点。

您可以注册任意数量的实现了 ResourceConfigCustomizer 的 bean,以实现更高级的定制功能。

所有注册的端点都应是具有 HTTP 资源注解( @GET 等)的 @Components,例如:

@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。 默认情况下,此 servlet 将被延迟初始化,您可以使用 spring.jersey.servlet.load-on-startup 进行自定义。您可以通过创建一个自己的同名文件来禁用或覆盖该 bean。您还可以通过设置 spring.jersey.type=filter 使用 Filter 替代 Servlet(这种情况下,用 @Bean 替代或者替换为 jerseyFilterRegistration)。此 servlet 有一个 @Order,您可以使用 spring.jersey.filter.order 设置。可以使用 spring.jersey.init.* 指定一个 properties map 以给定 Servlet 和 Filter 的初始化参数。

有一个 Jersey 示例,您可以了解到如何设置。还有一个 Jersey 1.x 示例。请注意,在 Jersey 1.x 示例中,spring-boot maven 插件已经被配置为解压一些 Jersey jar,以便他们可以被 JAX-RS 实现扫描到(因为示例要求他们在 Filter 注册中被扫描)。如果您有任何 JAX-RS 资源作为嵌套 jar 打包,您可能需要执行相同的操作。

27.3 嵌入式 servlet 容器支持

Spring Boot 包含了对嵌入式 Tomcat、Jetty 和 Undertow 服务器的支持。大多数开发人员将简单地使用合适的“Starter”来获取完整的配置实例。默认情况下,嵌入式服务器将监听 8080 上的 HTTP 请求。

[Warning] 警告

如果您选择在 CentOS 使用 Tomcat,请注意,默认情况下,临时目录用于储存编译后的 JSP、上传的文件等。当您的应用程序运行时发生了故障,该目录可能会被 tmpwatch 删除。为了避免这种情况,您可能需要自定义 tmpwatch 配置,以便 tomcat.* 目录不被删除,或者配置 server.tomcat.basedir 让 Tomcat 使用不同的位置。

27.3.1 Servlet、 Filter 与监听器

当使用嵌入式 servlet 容器时,您可以使用 Spring bean 或者扫描 Servlet 组件从 Servlet 规范(如 HttpSessionListener)注册 Servlet、Filter 和所有监听器。

将 Servlet、Filter 和监听器注册为 Spring bean

任何 ServletFilter 或者 Servlet *Listener 的 Spring bean 实例都将被注册到嵌入式容器中。如果您想在配置过程中引用您的 application.properties 中的值,这可能会特别方便。

默认情况下,如果上下文只包含单个 Servlet,它将映射到 /。 在多个 Servlet bean 的情况下,bean 的名称将用作路径的前缀。Filter 将映射到 /*

如果基于惯例的映射不够灵活,您可以使用 ServletRegistrationBean, FilterRegistrationBeanServletListenerRegistrationBean 类来完全控制。

27.3.2 Servlet 上下文初始化

嵌入式 servlet 容器不会直接执行 Servlet 3.0+ 的 javax.servlet.ServletContainerInitializer 接口或 Spring 的 org.springframework.web.WebApplicationInitializer 接口。这是一个有意的设计决策,旨在降低在 war 内运行时第三方类库产生的风险,防止破坏 Sring Boot 应用程序。

如果您需要在 Spring Boot 应用程序中执行 servlet 上下文初始化,则应注册一个实现了 org.springframework.boot.context.embedded.ServletContextInitializer 接口的 bean。 单个 onStartup 方法提供了对 ServletContext 的访问, 并且如果需要,可以轻松地用作现有 WebApplicationInitializer 的适配器。

扫描 Servlet、Filter 和监听器

使用嵌入式容器时,可以使用 @ServletComponentScan 启用 @WebServlet@WebFilter@WebListener 注解类的自动注册。

[Tip] 提示

@ServletComp onentScan 在独立(standalone)容器中不起作用,在该容器中将使用容器的内置发现机制。

27.3.3 EmbeddedWebApplicationContext

Spring Boot 底层使用了一个新的 ApplicationContext 类型来支持嵌入式 servlet 容器。EmbeddedWebApplicationContext 是一种特殊类型的 WebApplicationContext,它通过搜索单个 EmbeddedServletContainerFactory bean 来引导自身。通常,TomcatEmbeddedServletContainerFactoryJettyEmbeddedServletContainerFactory 或者 UndertowEmbeddedServletContainerFactory 将被自动配置。

[Note] 注意

你通常不需要知道这些实现类。大多数应用程序将被自动配置,并为您创建合适的 ApplicationContextEmbeddedServletContainerFactory

27.3.4 定制嵌入式 servlet 容器

可以使用 Spring Environment properties 配置常见的 servlet 容器设置。通常您可以在 application.properties 文件中定义 properties。

常用的服务器设置包括:

  • 网络设置:监听 HTTP 请求的端口(server.port), 绑定接口地址到 server.address
  • 会话设置:是否持久会话(server.session.persistence)、 session 超时(server.session.timeout)、会话数据存放位置( server.session.store-dir)和 session-cookie 配置(server.session.cookie.*)。
  • 错误管理:错误页面的位置(server.error.path)等。
  • SSL
  • HTTP compression

Spring Boot 尽可能尝试暴露常见的设置,但并不总是可能。对于这些情况,专用的命名空间提供了特定服务器的定制功能(请参阅 server.tomcatserver.undertow)。例如,可以使用嵌入式 servlet 容器的特定功能来配置 访问日志

[Tip] 提示

有关完整的列表,请参阅 ServerProperties 类。

编程形式定制

如果需要以编程的方式配置嵌入式 servlet 容器,您可以注册一个是实现了 EmbeddedServletContainerCustomizer 接口的 Spring bean。 EmbeddedServletContainerCustomizer 提供对 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

如果上述的定制技术有限,您可以自己注册 TomcatEmbeddedServletContainerFactoryJettyEmbeddedServletContainerFactoryUndertowEmbeddedServletContainerFactory bean。

@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 提供了许多配置选项。还有几个保护方法 “hooks” 供您深入定制。有关详细信息,请参阅源代码文档。

27.3.5 JSP 限制

当运行使用了嵌入式 servlet 容器的 Spring Boot 应用程序时(并打包为可执行归档文件),JSP 支持有一些限制。

  • 如果您使用 war 打包放入 Tomcat 中应该可以工作,例如,可执行 war 可以工作,并且可以被部署到标准的容器中(不限于 Tomcat)。由于 Tomcat 中的硬编码文件模式,可执行 jar 无法正常工作。
  • 如果您使用 war 打包配合 Jetty 使用应该可以工作,例如,可执行 war 可以工作,并且可以被部署到任意标准容器中。
  • Undertow 不支持 JSP。
  • 创建定制的 error.jsp 页面不会覆盖默认 错误处理 视图,应该使用 定制错误页面 代替。

这里有一个 JSP 示例,您可以了解到如何设置。

28. Security

If Spring Security is on the classpath then web applications will be secure by default with �basic� authentication on all HTTP endpoints. To add method-level security to a web application you can also add @EnableGlobalMethodSecurity with your desired settings. Additional information can be found in the Spring Security Reference.

The default AuthenticationManager has a single user (�user� username and random password, printed at INFO level when the application starts up)

Using default security password: 78fa095d-3f4c-48b1-ad50-e24c31d5cf35
[Note] Note

If you fine-tune your logging configuration, ensure that the org.springframework.boot.autoconfigure.security category is set to log INFO messages, otherwise the default password will not be printed.

You can change the password by providing a security.user.password. This and other useful properties are externalized via SecurityProperties (properties prefix "security").

The default security configuration is implemented in SecurityAutoConfiguration and in the classes imported from there (SpringBootWebSecurityConfiguration for web security and AuthenticationManagerConfiguration for authentication configuration which is also relevant in non-web applications). To switch off the default web application security configuration completely you can add a bean with @EnableWebSecurity (this does not disable the authentication manager configuration or Actuator�s security). To customize it you normally use external properties and beans of type WebSecurityConfigurerAdapter (e.g. to add form-based login). To also switch off the authentication manager configuration you can add a bean of type AuthenticationManager, or else configure the global AuthenticationManager by autowiring an AuthenticationManagerBuilder into a method in one of your @Configuration classes. There are several secure applications in the Spring Boot samples to get you started with common use cases.

The basic features you get out of the box in a web application are:

  • An AuthenticationManager bean with in-memory store and a single user (see SecurityProperties.User for the properties of the user).
  • Ignored (insecure) paths for common static resource locations (/css/**, /js/**, /images/**, /webjars/** and **/favicon.ico).
  • HTTP Basic security for all other endpoints.
  • Security events published to Spring�s ApplicationEventPublisher (successful and unsuccessful authentication and access denied).
  • Common low-level features (HSTS, XSS, CSRF, caching) provided by Spring Security are on by default.

All of the above can be switched on and off or modified using external properties ( security.*). To override the access rules without changing any other auto-configured features add a @Bean of type WebSecurityConfigurerAdapter with @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER) and configure it to meet your needs.

[Note] Note

By default, a WebSecurityConfigurerAdapter will match any path. If you don�t want to completely override Spring Boot�s auto-configured access rules, your adapter must explicitly configure the paths that you do want to override.

28.1 OAuth2

If you have spring-security-oauth2 on your classpath you can take advantage of some auto-configuration to make it easy to set up Authorization or Resource Server. For full details, see the Spring Security OAuth 2 Developers Guide.

28.1.1 Authorization Server

To create an Authorization Server and grant access tokens you need to use @EnableAuthorizationServer and provide security.oauth2.client.client-id and security.oauth2.client.client-secret] properties. The client will be registered for you in an in-memory repository.

Having done that you will be able to use the client credentials to create an access token, for example:

$ curl client:secret@localhost:8080/oauth/token -d grant_type=password -d username=user -d password=pwd

The basic auth credentials for the /token endpoint are the client-id and client-secret. The user credentials are the normal Spring Security user details (which default in Spring Boot to �user� and a random password).

To switch off the auto-configuration and configure the Authorization Server features yourself just add a @Bean of type AuthorizationServerConfigurer.

28.1.2 Resource Server

To use the access token you need a Resource Server (which can be the same as the Authorization Server). Creating a Resource Server is easy, just add @EnableResourceServer and provide some configuration to allow the server to decode access tokens. If your application is also an Authorization Server it already knows how to decode tokens, so there is nothing else to do. If your app is a standalone service then you need to give it some more configuration, one of the following options:

  • security.oauth2.resource.user-info-uri to use the /me resource (e.g. https://uaa.run.pivotal.io/userinfo on PWS)
  • security.oauth2.resource.token-info-uri to use the token decoding endpoint (e.g. https://uaa.run.pivotal.io/check_token on PWS).

If you specify both the user-info-uri and the token-info-uri then you can set a flag to say that one is preferred over the other (prefer-token-info=true is the default).

Alternatively (instead of user-info-uri or token-info-uri) if the tokens are JWTs you can configure a security.oauth2.resource.jwt.key-value to decode them locally (where the key is a verification key). The verification key value is either a symmetric secret or PEM-encoded RSA public key. If you don�t have the key and it�s public you can provide a URI where it can be downloaded (as a JSON object with a �value� field) with security.oauth2.resource.jwt.key-uri. E.g. on PWS:

$ curl https://uaa.run.pivotal.io/token_key
{"alg":"SHA256withRSA","value":"-----BEGIN PUBLIC KEY-----\nMIIBI...\n-----END PUBLIC KEY-----\n"}
[Warning] Warning

If you use the security.oauth2.resource.jwt.key-uri the authorization server needs to be running when your application starts up. It will log a warning if it can�t find the key, and tell you what to do to fix it.

OAuth2 resources are protected by a filter chain with order security.oauth2.resource.filter-order and the default is after the filter protecting the actuator endpoints by default (so actuator endpoints will stay on HTTP Basic unless you change the order).

28.2 Token Type in User Info

Google, and certain other 3rd party identity providers, are more strict about the token type name that is sent in the headers to the user info endpoint. The default is �Bearer� which suits most providers and matches the spec, but if you need to change it you can set security.oauth2.resource.token-type.

28.3 Customizing the User Info RestTemplate

If you have a user-info-uri, the resource server features use an OAuth2RestTemplate internally to fetch user details for authentication. This is provided as a @Bean of type UserInfoRestTemplateFactory. The default should be fine for most providers, but occasionally you might need to add additional interceptors, or change the request authenticator (which is how the token gets attached to outgoing requests). To add a customization just create a bean of type UserInfoRestTemplateCustomizer - it has a single method that will be called after the bean is created but before it is initialized. The rest template that is being customized here is only used internally to carry out authentication. Alternatively, you could define your own UserInfoRestTemplateFactory @Bean to take full control.

[Tip] Tip

To set an RSA key value in YAML use the �pipe� continuation marker to split it over multiple lines (�|�) and remember to indent the key value (it�s a standard YAML language feature). Example:

security:
    oauth2:
        resource:
            jwt:
                keyValue: |
                    -----BEGIN PUBLIC KEY-----
                    MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC...
                    -----END PUBLIC KEY-----

28.3.1 Client

To make your web-app into an OAuth2 client you can simply add @EnableOAuth2Client and Spring Boot will create a OAuth2ClientContext and OAuth2ProtectedResourceDetails that are necessary to create an OAuth2RestOperations. Spring Boot does not automatically create such bean but you can easily create your own:

@Bean
public OAuth2RestTemplate oauth2RestTemplate(OAuth2ClientContext oauth2ClientContext,
        OAuth2ProtectedResourceDetails details) {
    return new OAuth2RestTemplate(details, oauth2ClientContext);
}
[Note] Note

You may want to add a qualifier and review your configuration as more than one RestTemplate may be defined in your application.

This configuration uses security.oauth2.client.* as credentials (the same as you might be using in the Authorization Server), but in addition it will need to know the authorization and token URIs in the Authorization Server. For example:

application.yml. 

security:
    oauth2:
        client:
            clientId: bd1c0a783ccdd1c9b9e4
            clientSecret: 1a9030fbca47a5b2c28e92f19050bb77824b5ad1
            accessTokenUri: https://github.com/login/oauth/access_token
            userAuthorizationUri: https://github.com/login/oauth/authorize
            clientAuthenticationScheme: form

An application with this configuration will redirect to Github for authorization when you attempt to use the OAuth2RestTemplate. If you are already signed into Github you won�t even notice that it has authenticated. These specific credentials will only work if your application is running on port 8080 (register your own client app in Github or other provider for more flexibility).

To limit the scope that the client asks for when it obtains an access token you can set security.oauth2.client.scope (comma separated or an array in YAML). By default the scope is empty and it is up to Authorization Server to decide what the defaults should be, usually depending on the settings in the client registration that it holds.

[Note] Note

There is also a setting for security.oauth2.client.client-authentication-scheme which defaults to �header� (but you might need to set it to �form� if, like Github for instance, your OAuth2 provider doesn�t like header authentication). In fact, the security.oauth2.client.* properties are bound to an instance of AuthorizationCodeResourceDetails so all its properties can be specified.

[Tip] Tip

In a non-web application you can still create an OAuth2RestOperations and it is still wired into the security.oauth2.client.* configuration. In this case it is a �client credentials token grant� you will be asking for if you use it (and there is no need to use @EnableOAuth2Client or @EnableOAuth2Sso). To prevent that infrastructure to be defined, just remove the security.oauth2.client.client-id from your configuration (or make it the empty string).

28.3.2 Single Sign On

An OAuth2 Client can be used to fetch user details from the provider (if such features are available) and then convert them into an Authentication token for Spring Security. The Resource Server above support this via the user-info-uri property This is the basis for a Single Sign On (SSO) protocol based on OAuth2, and Spring Boot makes it easy to participate by providing an annotation @EnableOAuth2Sso. The Github client above can protect all its resources and authenticate using the Github /user/ endpoint, by adding that annotation and declaring where to find the endpoint (in addition to the security.oauth2.client.* configuration already listed above):

application.yml. 

security:
    oauth2:
...
    resource:
        userInfoUri: https://api.github.com/user
        preferTokenInfo: false

Since all paths are secure by default, there is no �home� page that you can show to unauthenticated users and invite them to login (by visiting the /login path, or the path specified by security.oauth2.sso.login-path).

To customize the access rules or paths to protect, so you can add a �home� page for instance, @EnableOAuth2Sso can be added to a WebSecurityConfigurerAdapter and the annotation will cause it to be decorated and enhanced with the necessary pieces to get the /login path working. For example, here we simply allow unauthenticated access to the home page at "/" and keep the default for everything else:

@Configuration
static class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    public void init(WebSecurity web) {
        web.ignoring().antMatchers("/");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.antMatcher("/**").authorizeRequests().anyRequest().authenticated();
    }

}

28.4 Actuator Security

If the Actuator is also in use, you will find:

  • The management endpoints are secure even if the application endpoints are insecure.
  • Security events are transformed into AuditEvent instances and published to the AuditEventRepository.
  • The default user will have the ACTUATOR role as well as the USER role.

The Actuator security features can be modified using external properties ( management.security.*). To override the application access rules add a @Bean of type WebSecurityConfigurerAdapter and use @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER) if you don�t want to override the actuator access rules, or @Order(ManagementServerProperties.ACCESS_OVERRIDE_ORDER) if you do want to override the actuator access rules.

29. 使用 SQL 数据库

Spring Framework 为 SQL 数据库提供了广泛的支持。从直接使用 JdbcTemplate 进行 JDBC 访问到完全的“对象关系映射(object relational mapping)”技术,例如 Hibernate。Spring Data 提供了 额外的功能级别,直接从接口创建的 Repository 实现,并使用了约定从方法名生成查询。

29.1 配置数据源

Java 的 javax.sql.DataSource 接口提供了一个使用数据库连接的标准方法。通常数据源使用 URL 和一些凭据来建立数据库连接。

[Tip] 提示

查看 “How-to” 部分 获取更多高级示例,通常可以完全控制数据库的配置。

29.1.1 嵌入式数据库支持

使用嵌入式内存数据库来开发应用程序是很方便的。显然,内存数据库不需要提供持久存储;在应用启动时,您将需要填充数据库,并准备在应用程序结束时丢弃数据。

[Tip] 提示

“How-to”部分包含了 怎样初始化数据库部分

Spring Boot 可以自动配置嵌入式 H2HSQLDerby 数据库。您不需要提供任何连接 URL,只需将构建依赖包含到要使用的嵌入式数据库中即可。

[Note] 注意

如果您在测试中使用此功能,您可能会注意到,整个测试套件都会重复使用相同的数据库,而不管您使用了多少应用程序上下文。 如果要确保每隔上下文都有一个单独的嵌入式数据库,您应该将 spring.datasource.generate-unique-name 设置为 true

例如,典型的 POM 依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>org.hsqldb</groupId>
    <artifactId>hsqldb</artifactId>
    <scope>runtime</scope>
</dependency>
[Note] 注意

对于要自动配置的嵌入式数据库,您需要依赖 spring-jdbc。在这个例子中,它是通过 spring-boot-starter-data-jpa 传递的。

[Tip] 提示

如果由于某种原因配置嵌入式数据库的连接,则应注意确保数据库的自动关闭被禁用。如果您使用 H2,您应该设置 DB_CLOSE_ON_EXIT=FALSE。如果您使用 HSQLDB,则确保不使用 shutdown=true。禁用数据库的自动关闭允许 Spring Boot 控制数据库何时关闭,从而确保在访问数据库时只发生一次,以后将不在需要。

29.1.2 连接到生产数据库

生产数据库连接也可以使用使用 DataSource 自动配置。这是选择具体的实现算法:

  • 我们更喜欢 Tomcat 连接池 DataSource 的性能和并发性, 如果可用,我们总是选择它。
  • 否则,如果 HikariCP 可用,我们将使用它。
  • 如果 Tomcat 连接池数据源和 HikariCP 不可用,并且如果 Commons DBCP 可用,我们将使用它,但是我们不建议在生产中使用它,并且它的支持已经过时。
  • 最后,如果 Commons DBCP2 可用,我们将使用它。

如果您使用了 spring-boot-starter-jdbc 或者 spring-boot-starter-data-jpa “starter”,您将自动获得对 tomcat-jdbc 的依赖。

[Note] 注意

您完全可以绕过该算法,并通过 spring.datasource.type property 指定要使用的连接池。如果您在 Tomcat 容器中运行应用程序,默认情况下提供 tomcat-jdbc,这点尤为重要。

[Tip] 提醒

可以手动配置其他连接池。如果您定义了自己的 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
[Note] 注意

您应至少使用 spring.datasource.url property 指定 url,否则 Spring Boot 将尝试自动配置嵌入式数据库。

[Tip] 提示

通常您不需要指定 driver-class-name,因为 Spring boot 可以从 url 推导出大多数数据库。

[Note] 注意

对于要创建的连接池 DataSource,我们需要能够验证有效的 Driver 类是否可用,所以我们在做任何事之前检查它。例如,如果您设置了 spring.datasource.driver-class-name=com.mysql.jdbc.Driver,那么该类必须可加载。

有关更多支持的选项,请参阅 DataSourceProperties。这些都是标准选项,与实际的实现无关。还可以使用各自的前缀(spring.datasource.tomcat.*spring.datasource.hikari.*spring.datasource.dbcp2.*)微调实现特定的设置。 有关更多关于您正在使用的连接池的实现的详细信息,请参阅文档。

例如,如果你正在使用 Tomcat 连接池,您可以自定义许多其他设置:

# Number of ms to wait before throwing an exception if no connection is available.
spring.datasource.tomcat.max-wait=10000

# Maximum number of active connections that can be allocated from this pool at the same time.
spring.datasource.tomcat.max-active=50

# Validate the connection before borrowing it from the pool.
spring.datasource.tomcat.test-on-borrow=true

29.1.3 连接到 JNDI 数据源

如果要将 Spring Boot 应用程序部署到应用服务器上,您可能需要使用应用程序服务器内置功能来配置和管理数据源,并使用 JNDI 进行访问。

spring.datasource.jndi-name property 可以用作 spring.datasource.url, spring.datasource.usernamespring.datasource.password properties 的替代方法,以从特定的 JNDI 位置访问 DataSource。例如,application.properties 中的以下部分展示了如何访问 JBoss AS 定义的 DataSource

spring.datasource.jndi-name=java:jboss/datasources/customers

29.2 使用 JdbcTemplate

Spring 的 JdbcTemplateNamedParameterJdbcTemplate 类是自动配置的,您可以将它们直接 @Autowire 到您的 bean 中:

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;

            @Autowired
            public MyBean(JdbcTemplate jdbcTemplate)
            {
            this.jdbcTemplate = jdbcTemplate; }

            // ... }

            

29.3 JPA 与 Spring Data

Java Persistence API 是一中标准技术,可让您将对象“映射”到关系数据库。spring-boot-starter-data-jpa POM 提供了一个快速入门的方法。它提供了以下关键依赖:

  • Hibernate - 最受欢迎的 JPA 实现之一。
  • Spring Data JPA - 可以轻松地实现基于 JPA 的资源库。
  • Spring ORMs - Spring Framework 的核心 ORM 支持
[Tip] 提示

我们不会在这里介绍太多关于 JPA 或者 Spring Data 的细节。您可以在 spring.io 上查看 使用 JPA 访问数据,并阅读 Spring Data JPAHibernate 参考文档。

[Note] 注意

默认情况下,Spring Boot 使用 Hibernate 5.0.x。然而,如果您愿意,也可以使用 4.3.x 或者 5.2.x。请参阅 Hibernate 4Hibernate 5.2 示例,看看如何做到这点。

29.3.1 实体类

通常,JPA “Entity” 类是在 persistence.xml 文件中指定的。使用了 Spring Boot,此文件将不是必需的,可以使用“Entity Scanning”来代替。默认情况下,将搜索主配置类下面的所有包(用 @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

}
[Tip] 提示

您可以使用 @EntityScan 注解自定义实体类的扫描位置。请参见 章节 77.4、从 Spring configuration配置中分离 @Entity 定义

29.3.2 Spring Data JPA 资源库

Spring Data JPA 资源库(repository)是可以定义用于访问数据的接口。JAP 查询是根据您的方法名自动创建。例如,CityRepository 接口可以声明 findAllByState(String state) 方法来查找指定状态下的所有城市。

对于更加复杂的查询,您可以使用 Spring Data 的 Query 注解

对方法进行注解。

Spring Data 资源库通常继承自 Repository 或者 CrudRepository 接口。如果您正在使用自动配置, 那么将从包含主配置类的包(通过 @EnableAutoConfiguration@SpringBootApplication 注解)中搜索资源库。 down.

这是一个典型的 Spring Data 资源库:

package com.example.myapp.domain;

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

public interface CityRepository extends Repository<City, Long> {

    Page<City> findAll(Pageable pageable);

    City findByNameAndCountryAllIgnoringCase(String name, String country);

}
[Tip] 提示

我们几乎没有接触到 Spring Data JPA 的表面内容。有关完整的详细信息,请查阅 参考文档

29.3.3 创建和删除 JPA 数据库

默认情况下,仅当 您使用了嵌入式数据库(H2、HSQL 或 Derby)时才会自动创建 JPA 数据库。您可以使用 spring.jpa.* properties 显示配置 JPA 设置。例如,要创建和删除表,您可以将以下内容添加到 application.properties 中。

spring.jpa.hibernate.ddl-auto=create-drop
[Note] 注意

Hibernate 自己的内部属性名称(如果您记住更好)是 hibernate.hbm2ddl.auto。您可以使用 spring.jpa.properties.* (将前缀删除,然后将其添加到实体管理器)与其他 Hibernate 本地 properties 一起设置。例如:

spring.jpa.properties.hibernate.globally_quoted_identifiers=true

hibernate.globally_quoted_identifiers 传递给 Hibernate 实体管理器。

默认情况下,DDL 执行(或验证)将延迟到 ApplicationContext 启动后。还有一个 spring.jpa.generate-ddl 标志,如果 Hibernate 自动配置是激活的,那么它将不会被使用,因为 ddl-auto 设置更加细。

29.3.4 在 View 中打开 EntityManager

如果您正在运行 web 应用程序,Spring Boot 将默认注册 OpenEntityManagerInViewInterceptor 来应用“在 View 中打开 EntityManager”模式,即运允许在 web 视图中延迟加载。如果您不想要这个行为,您应该在您的 application.properties 中将 spring.jpa.open-in-view 设置为 false

29.4 使用 H2 的 web 控制台

H2 数据库 提供了一个 基于浏览器的控制台,Spring Boot 可以为您自动配置。满足以下条件时,控制台将自动配置:

[Tip] 提示

如果您不使用 Spring Boot 的开发者工具,但仍希望使用 H2 的控制台,那么可以通过将 spring.h2.console.enabled property 设置为 true 来实现。H2 控制台仅用于开发期间,因此应注意确保 spring.h2.console.enabled 在生产环境中未设置为 true

29.4.1 更改 H2 控制台的路径

默认情况下,控制台在 /h2-console 上可用。你可以使用 spring.h2.console.path 属性来自定义控制台的路径。

29.4.2 保护 H2 控制台

当 Spring Security 位于 classpath 上且启用了基本身份验证,H2 console 将使用基本身份验证自动保护。以下属性可用于自定义安全属性:

  • security.user.role
  • security.basic.authorize-mode
  • security.basic.enabled

29.5 使用 jOOQ

Java 面向对象查询(Java Object Oriented Querying,jOOQ)是 Data Geekery 的一款受欢迎的产品,它从数据库生成代码,并通过链式 API 构建类型安全的 SQL 查询。商业版和开源版都可以与 Spring Boot 一起使用。

29.5.1 代码生成

为了使用 jOOQ 的类型安全查询,您需要藏数据库模式生成 Java 类。您可以按照 jOOQ 用户手册 中的说明进行操作。 如果您正在使用 jooq-codegen-maven 插件(并且还使用了 spring-boot-starter-parent 父 POM),您可以安全地省略掉插件的 <version> 标签。您还可以使用 Spring Boot 定义的版本变量(例如 h2.version)来声明插件的数据库依赖。以下是一个示例:

<plugin>
    <groupId>org.jooq</groupId>
    <artifactId>jooq-codegen-maven</artifactId>
    <executions>
        ...
    </executions>
    <dependencies>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>${h2.version}</version>
        </dependency>
    </dependencies>
    <configuration>
        <jdbc>
            <driver>org.h2.Driver</driver>
            <url>jdbc:h2:~/yourdatabase</url>
        </jdbc>
        <generator>
            ...
        </generator>
    </configuration>
</plugin>

29.5.2 使用 DSLContext

JOOQ 提供的链式 API 是通过 org.jooq.DSLContext 接口初始化的。 Spring Boot 将自动配置一个 DSLContext 作为 Spring Bean,并且将其连接到应用程序的 DataSource。要使用 DSLContext,您只需要 @Autowire 它:

@Component
public class JooqExample implements CommandLineRunner {

    private final DSLContext create;

    @Autowired
    public JooqExample(DSLContext dslContext) {
        this.create = dslContext;
    }

}
[Tip] 提示

jOOQ 手册趋向于使用名为 create 的变量来保存 DSLContext,我们在此示例中也是这样。

您可以使用 DSLContext 构建查询:

public List<GregorianCalendar> authorsBornAfter1980() {
    return this.create.selectFrom(AUTHOR)
        .where(AUTHOR.DATE_OF_BIRTH.greaterThan(new GregorianCalendar(1980, 0, 1)))
        .fetch(AUTHOR.DATE_OF_BIRTH);
}

29.5.3 定制 jOOQ

您可以通过在 application.properties 中设置 spring.jooq.sql-dialect 来定制 JOOQ 使用的方言。例如,要指定 Postgres,您可以添加:

spring.jooq.sql-dialect=Postgres

通过定义自己的 @Bean 定义可以实现更高级的自定义,这些定义将在创建 jOOQ Configuration 时被使用。您可以为以下 jOOQ 类型定义:

  • ConnectionProvider
  • TransactionProvider
  • RecordMapperProvider
  • RecordListenerProvider
  • ExecuteListenerProvider
  • VisitListenerProvider

如果要完全控制 jOOQ 配置,您还可以创建自己的 org.jooq.Configuration @Bean

30. 使用 NoSQL 技术

Spring Data 提供了额外的项目,可以帮助您访问各种 NoSQL 技术,包括 MongoDBNeo4JElasticsearchSolrRedisGemfireCassandraCouchbaseLDAP。Spring Boot 为 Redis、MongoDB、Neo4j、Elasticsearch、Solr Cassandra、Couchbase 和 LDAP 提供了自动配置;您也可以使用其他项目,但您需要自行配置他们。请参阅 projects.spring.io/spring-data 中相应的参考文档。

30.1 Redis

Redis 是一个缓存、消息代理和功能丰富的键值存储。Spring Boot 提供了 Jedis 客户端类库的基本自动配置,Spring Data Redis 提供了上层抽象。 有一个 spring-boot-starter-data-redis 的“Starter”收集了相关的依赖。

30.1.1 连接到 Redis

您可以像任何 Spring Bean 一样注入自动配置的 RedisConnectionFactoryStringRedisTemplate 或普通的 RedisTemplate 实例。默认情况下,实例将尝试使用 localhost:6379 连接到 Redis 服务器:

@Component
                    public class MyBean {

                    private StringRedisTemplate template;

                    @Autowired
                    public MyBean(StringRedisTemplate
                    template) {
                    this.template = template; }

                    // ... }

                    

如果您添加了您自己的任何自动配置类型的 @Bean,它将替换掉默认值(除了在 RedisTemplate 情况下,排除是基于 bean 名称为 “redisTemplate”而不是其类型)。如果 commons-pool2 在 classpath 上,则默认情况下将获得一个连接池工厂。

30.2 MongoDB

MongoDB 是一个开源的 NoSQL 文档数据库,它使用了类似 JSON 的模式(schema),而不是传统的基于表的关系数据。Spring Boot 为 MongoDB 提供了几种便利,包括 spring-boot-starter-data-mongodb “Starter”。

30.2.1 连接 MongoDB 数据库

你可以注入一个自动配置的 org.springframework.data.mongodb.MongoDbFactory 来访问 Mongo 数据库。默认情况下,实例将尝试使用 URL mongodb://localhost/test 连接到 MongoDB 服务器:

import org.springframework.data.mongodb.MongoDbFactory;
import com.mongodb.DB;

@Component
public class MyBean {

    private final MongoDbFactory mongo;

    @Autowired
    public MyBean(MongoDbFactory mongo) {
        this.mongo = mongo;
    }

    // ...

    public void example() {
        DB db = mongo.getDb();
        // ...
    }

}

您可以设置 spring.data.mongodb.uri 属性来更改 URL 和配置其他设置,如 副本集(replica set)

spring.data.mongodb.uri=mongodb://user:secret@mongo1.example.com:12345,mongo2.example.com:23456/test

另外,只要您使用 Mongo 2.x,请指定 host/port。 例如,您可能在 application.properties 中声明以下内容:

spring.data.mongodb.host=mongoserver
                spring.data.mongodb.port=27017
[Note] 注意

如果您使用 Mongo 3.0 Java 驱动,则不支持 spring.data.mongodb.hostspring.data.mongodb.port。这种情况下,应该使用 spring.data.mongodb.uri 来提供所有配置。

[Tip] 提示

如果未指定 spring.data.mongodb.port,则使用默认值 27017。您可以从上面的示例中简单地删除该行。

[Tip] 提示

如果您不使用 Spring Data Mongo,您应该注入 com.mongodb.Mongo bean 而不是使用 MongoDbFactory

如果要完全控制建立 MongoDB 连接,您还可以声明您自己的 MongoDbFactory 或者 Mongo bean。

30.2.2 MongoTemplate

Spring Data Mongo 提供了一个 MongoTemplate 类,它的设计与 Spring 的 JdbcTemplate 非常相似。与 JdbcTemplate Spring Boot 自动配置 bean 一样,您只需要注入:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

    private final MongoTemplate mongoTemplate;

    @Autowired
    public MyBean(MongoTemplate mongoTemplate) {
        this.mongoTemplate = mongoTemplate;
    }

    // ...

}

有关详细信息,请参阅 MongoOperations Javadoc。

30.2.3 Spring Data MongoDB 仓储

Spring Data 包含了 MongoDB 仓储(repository)支持。 与之前讨论的 JPA 仓储一样,基本原理是根据方法名称自动构建查询。

事实上,Spring Data JPA 和 Spring Data MongoDB 共享通用的底层代码;因此你可以拿之前提到的 JPA 示例作为基础,假设 City 现在是一个 Mongo 数据类而不是一个 JPA @Entity,它将以相同的方式工作。

package com.example.myapp.domain;

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

public interface CityRepository extends Repository<City, Long> {

    Page<City> findAll(Pageable pageable);

    City findByNameAndCountryAllIgnoringCase(String name, String country);

}
[Tip] 提示

有关 Spring Data MongoDB 的完整详细内容,包括其丰富的对象关系映射技术,请参考其 参考文档

30.2.4 嵌入式 Mongo

Spring Boot 提供了 嵌入式(Embedded) Mongo 的自动配置。 要在 Spring Boot 应用中使用它,请添加依赖 de.flapdoodle.embed:de.flapdoodle.embed.mongo

可以使用 spring.data.mongodb.port 属性来配置 Mongo 的监听端口。要使用一个随机分配的空闲端口,请把值设置为 0。MongoAutoConfiguration 创建的 MongoClient 将自动配置随机分配的端口。

[Note] 注意

如果您不配置一个自定义的端口,嵌入式支持将默认使用一个随机端口(而不是 27017)。

如果您的 classpath 上有 SLF4J,Mongo 生成输出将自动路由到名为 org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongo 的 logger。

您可声明自己的 IMongodConfigIRuntimeConfig bean 来控制 Mongo 实例的配置和日志记录路由。

30.3 Neo4j

Neo4j 是一个开源的 NoSQL 图数据库,它使用了一个与一级关系相关的节点的富数据模型,它比传统的 RDBMS 方法更适合连接大数据。Spring Boot 为 Neo4j 提供了便捷方式,包括 spring-boot-starter-data-neo4j Starter。

30.3.1 连接 Neo4j 数据库

您可以像任何其他 Spring Bean 一样注入一个自动配置的 Neo4jSessionSession 或者 Neo4jOperations。默认情况下, 实例将尝试使用 localhost:7474 连接到 Neo4j 服务器:

@Component
                public class MyBean {

                private final Neo4jTemplate neo4jTemplate;

                @Autowired
                public MyBean(Neo4jTemplate neo4jTemplate)
                {
                this.neo4jTemplate = neo4jTemplate;
                }

                // ... }

                

您可以通过添加自己的 org.neo4j.ogm.config.Configuration @Bean 来完全控制 配置。此外,添加 Neo4jOperations 类型的 @Bean 会禁用自动配置。

您可以通过 spring.data.neo4j.* 属性来配置用户和凭据:

spring.data.neo4j.uri=http://my-server:7474
spring.data.neo4j.username=neo4j
spring.data.neo4j.password=secret

30.3.2 使用内嵌模式

如果您将 org.neo4j:neo4j-ogm-embedded-driver 添加到应用程序的依赖中,Spring Boot 将自动配置一个进程内内嵌 Neo4j 实例,当您的应用程序关闭时,该实例将不会保留任何数据。您可以使用 spring.data.neo4j.embedded.enabled=false 显示禁用该模式。 您也可以为内嵌模式开启持久化:

	spring.data.neo4j.uri=file://var/tmp/graph.db
[Note] 注意

Neo4j OGM 嵌入式驱动不提供 Neo4j 内核。用户应该手动提供此依赖关系,有关详细信息,请参阅文档

30.3.3 Neo4jSession

默认情况下,如果您正在运行 Web 应用程序,该会话将被绑定到当前请求的整个处理线程(即“Open Session in View”模式)。如果您不希望此行为,可以在 application.properties 中添加以下内容:

	spring.data.neo4j.open-in-view=false

30.3.4 Spring Data Neo4j 仓储

Spring Data 包括了 Neo4j 仓储支持。

事实上,Spring Data JPA 与 Spring Data Neo4j 共享了相同的通用底层代码;因此您可以直接把之前的 JPA 示例作为基础,假设 City 现在是一个 Neo4j OGM @NodeEntity,而不是一个 JPA @Entity,它将以相同的方式工作。

[Tip] 提示

您可以使用 @EntityScan 注解来定制实体类的扫描位置。

要启用仓储支持(且选择性地支持 @Transactional),请将以下两个注解添加到您的 Spring 配置中:

@EnableNeo4jRepositories(basePackages = "com.example.myapp.repository")
@EnableTransactionManagement

30.3.5 仓储示例

package com.example.myapp.domain;

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

public interface CityRepository extends GraphRepository<City> {

    Page<City> findAll(Pageable pageable);

    City findByNameAndCountry(String name, String country);

}
[Tip] Tip

有关 Spring Data Neo4j 的完整详细内容,包括其丰富的对象关系映射技术支持,请参阅其 参考文档

30.4 Gemfire

Spring Data Gemfire 提供了便捷的 Spring 友好工具,用于访问 Pivotal Gemfire 数据管理平台。spring-boot-starter-data-gemfire Starter 收集了相关依赖。目前没有针对 Gemfire 的自动配置支持,但您可以使用一个 单独的注解 (@EnableGemfireRepositories 来启用 Spring Data 仓储。

30.5 Solr

Apache Solr 是一个搜素引擎。Spring Boot 为 Solr 5 客户端类库提供了基本的自动配置,且抽象 Spring Data Solr 为其提供给了顶层抽象。相关的依赖包含在了 spring-boot-starter-data-solr Starter 中。

30.5.1 连接 Solr

您可以向任何其他 Spring Bean 一样注入一个自动配置的 SolrClient 实例。默认情况下,实例将尝试通过 localhost:8983/solr 连接到服务器:

@Component
                public class MyBean {

                private SolrClient solr;

                @Autowired
                public MyBean(SolrClient solr) {
                this.solr = solr; }

                // ... }

                

如果您添加了一个自己的 SolrClient 类型的 @Bean,它将替换掉默认值。

30.5.2 Spring Data Solr 仓储

Spring Data 包含了 Apache Solr 仓储支持。与之前讨论的 JPA 仓储一样,基本原理是根据方法名称自动构建查询。

事实上,Spring Data JPA 和 Spring Data Solr 共享了相同的通用底层代码;因此您可以使用之前的 JPA 示例作为基础,假设 City 现在是一个 @SolrDocument 类,而不是一个 JPA @Entity, 他将以相同的方式工作。

[Tip] 提示

有关 Spring Data Solr 的完整详细内容,请参考其 参考文档

30.6 Elasticsearch

Elasticsearch 是一个开源、分布式的实时搜索分析引擎。Spring Boot 为 Elasticsearch 提供了基本的自动配置,且 Spring Data Elasticsearch 为其提供了底层抽象。有关的依赖包含在了 spring-boot-starter-data-elasticsearch Starter 中。Spring Boot 同样支持 Jest

30.6.1 使用 Jest 连接 Elasticsearch

如果您的 classpath 上存在 Jest,则您可以注入一个默认指向 localhost:9200 的自动配置的 JestClient。您可以进一步地调整客户端配置:

spring.elasticsearch.jest.uris=http://search.example.com:9200
spring.elasticsearch.jest.read-timeout=10000
spring.elasticsearch.jest.username=user
spring.elasticsearch.jest.password=secret

您还可以注册任何数量的实现了 HttpClientConfigBuilderCustomizer 的 bean 进行更加高级的定制。以下示例调用了其他 HTTP 设置:

static class HttpSettingsCustomizer implements HttpClientConfigBuilderCustomizer {

    @Override
    public void customize(HttpClientConfig.Builder builder) {
        builder.maxTotalConnection(100).defaultMaxTotalConnectionPerRoute(5);
    }

}

要完全控制注册,请定义一个 JestClient bean。

30.6.2 使用 Spring Data 连接 Elasticsearch

您可以像任何其他 Spring Bean 一样注入一个自动配置的 ElasticsearchTemplate 或者 Elasticsearch 的 Client 实例。默认情况下,实例将嵌入一个本地内存服务器(一个 Elasticsearch 术语 Node),且使用当前的工作目录作为服务器的主目录。在此设置中,首先得要告诉 Elasticsearch 存储其文件的位置:

spring.data.elasticsearch.properties.path.home=/foo/bar

或者,您可以通过将 spring.data.elasticsearch.cluster-nodes 设置为以逗号分割的“host:port”列表来切换远程服务器(比如 TransportClient)。

spring.data.elasticsearch.cluster-nodes=localhost:9300
@Component
                    public class MyBean {

                    private ElasticsearchTemplate
                    template;

                    @Autowired
                    public MyBean(ElasticsearchTemplate
                    template) {
                    this.template = template; }

                    // ... }

                    

如果您添加了一个自己的 ElasticsearchTemplate 类型的 @Bean,它将替换掉默认值。

30.6.3 Spring Data Elasticsearch 仓储

Spring Data 包含了对 Elasticsearch 仓储的支持,与之前讨论的 JPA 仓储一样,其原理是根据方法名称自动构建查询。

事实上,Spring Data JPA 与 Spring Data Elasticsearch 共享了相同的通用底层代码;因此您可以使用之前的 JPA 示例作为基础,假设 City 此时是一个 Elasticsearch @Document 类,而不是一个 JPA @Entity,它将以同样的方式工作。

[Tip] 提示

有关 Spring Data Elasticsearch 的完整详细内容,请参阅其 参考文档

30.7 Cassandra

Cassandra 是一个开源的分布式数据库管理系统,旨在处理商品服务器(commodity servers)上的大量。Spring Boot 为 Cassandra 提供了基本的自动配置,且 Spring Data Cassandra 为其提供了顶层抽象。相关依赖包含在了 spring-boot-starter-data-cassandra Starter 中。

30.7.1 连接 Cassandra

您可以像任何其他 Spring Bean 一样注入一个自动配置的 CassandraTemplate 或 Cassandra 的 Session 实例。spring.data.cassandra.* 可用于自定义连接。通常提供 keyspace-namecontact-points 属性:

spring.data.cassandra.keyspace-name=mykeyspace
                spring.data.cassandra.contact-points=cassandrahost1,cassandrahost2
@Component
                    public class MyBean {

                    private CassandraTemplate template;

                    @Autowired
                    public MyBean(CassandraTemplate
                    template) {
                    this.template = template; }

                    // ... }

                    

如果您添加了一个自己的 CassandraTemplate 类型的 @Bean,它将替换掉默认值。

30.7.2 Spring Data Cassandra 仓储

Spring Data 包含了基本的 Cassandra 仓储支持。当前,这比之前讨论的 JPA 仓储更受限制,并且需要在 finder 方法上使用 @Query 注解。

[Tip] 提示

有关 Spring Data Cassandra 的完整详细内容,请参阅其 参考文档

30.8 Couchbase

Couchbase 是一个开源、分布式多模型 NoSQL 面向文档数据库,其针对交互式应用程序做了优化。Spring Boot 为 Couchbase 提供了基本的自动配置,且 Spring Data Couchbase 为其提供了顶层抽象。 相关的依赖包含在了 spring-boot-starter-data-couchbase Starter 中。

30.8.1 连接 Couchbase

您可以通过添加 Couchbase SDK 和一些配置来轻松获取 BucketClusterspring.couchbase.* 属性可用于自定义连接。通常配置 bootstrap hosts、bucket name 和 password:

spring.couchbase.bootstrap-hosts=my-host-1,192.168.1.123
spring.couchbase.bucket.name=my-bucket
spring.couchbase.bucket.password=secret
[Tip] 提示

您需要 至少 提供 bootstrap host,如果这样,bucket name 为 default 且 password 为空字符串。或者,您可以定义自己的 org.springframework.data.couchbase.config.CouchbaseConfigurer @Bean 来控制整个配置。

也可以自定义一些 CouchbaseEnvironment 设置。例如,以下配置修改了打开一个新 Bucket 的超时时间和开启了 SSL 支持:

spring.couchbase.env.timeouts.connect=3000
spring.couchbase.env.ssl.key-store=/location/of/keystore.jks
spring.couchbase.env.ssl.key-store-password=secret

参阅 spring.couchbase.env.* 以获取更多详细信息。

30.8.2 Spring Data Couchbase 仓储

Spring Data 包含了 Couchbase 仓储支持。有关 Spring Data Couchbase 的完整详细信息,请参阅其参考文档

只要 默认的 CouchbaseConfigurer 可用 (如上所述,启用 couchbase 支持时生效),您可以像任何其他 Spring Bean 一样注入一个自动配置的 CouchbaseTemplate 实例。

@Component
public class MyBean {

    private final CouchbaseTemplate template;

    @Autowired
    public MyBean(CouchbaseTemplate template) {
        this.template = template;
    }

    // ...

}

您可以在自己的配置中定义以下几个 bean,以覆盖自动配置提供的配置:

  • 一个名为 couchbaseTemplateCouchbaseTemplate @Bean
  • 一个名为 couchbaseIndexManagerIndexManager @Bean
  • 一个名为 couchbaseCustomConversionsCustomConversions @Bean

为避免在自己的配置中对这些名称硬编码,您可以重用 Spring Data Couchbase 提供的 BeanNames,例如,您可以自定义转换器,如下:

@Configuration
public class SomeConfiguration {

    @Bean(BeanNames.COUCHBASE_CUSTOM_CONVERSIONS)
    public CustomConversions myCustomConversions() {
        return new CustomConversions(...);
    }

    // ...

}
[Tip] Tip

如果您想要安全绕开 Spring Data Couchbase 的自动配置,请提供您自己的 org.springframework.data.couchbase.config.AbstractCouchbaseDataConfiguration 实现。

30.9 LDAP

LDAP(Lightweight Directory Access Protocol,轻量级目录访问协议)是一个开放、厂商中立的行业标准应用协议,其通过 IP 网络访问和维护分布式目录信息服务。Spring Boot 为兼容 LDAP 服务器提供了自动配置,以及从 UnboundID 支持嵌入式内存 LDAP 服务器。

Spring Data LDAP 提供了 LDAP 抽象。相关依赖包含在了 spring-boot-starter-data-ldap Starter 中。

30.9.1 连接 LDAP 服务器

要连接到 LDAP 服务器,请确保您已经声明了 spring-boot-starter-data-ldap Starter 或者 spring-ldap-core 引入相关依赖,然后在 application.properties 声明服务器的 URL:

spring.ldap.urls=ldap://myserver:1235
spring.ldap.username=admin
spring.ldap.password=secret

If you need to customize connection settings you can use the spring.ldap.base and spring.ldap.base-environment properties.

30.9.2 Spring Data LDAP 仓储

Spring Data 包含了 LDAP 仓储支持。有关 Spring Data LDAP 的完整详细信息,请参阅其 参考文档

您还可以像任何其他 Spring Bean 一样注入一个自动配置的 LdapTemplate 实例。

@Component
public class MyBean {

    private final LdapTemplate template;

    @Autowired
    public MyBean(LdapTemplate template) {
        this.template = template;
    }

    // ...

}

30.9.3 嵌入式 LDAP 内存服务器

为了测试目的,Spring Boot 支持从 UnboundID 自动配置 LDAP 内存服务器。要配置服务器,请添加 com.unboundid:unboundid-ldapsdk 依赖并声明一个 base-dn 属性:

spring.ldap.embedded.base-dn=dc=spring,dc=io

默认情况下,服务器将在一个随机端口上启动,并触发常规的 LDAP 支持(不需要指定 spring.ldap.urls 属性)。

如果您的 classpath 存在一个 schema.ldif 文件,其将用于初始化服务器。如果要从不同的资源加载中加载脚本,可以使用 spring.ldap.embedded.ldif 属性。

默认情况下,将使用一个标准模式(schema)来校验 LDIF 文件。您可以使用 spring.ldap.embedded.validation.enabled 属性来完全关闭校验。如果您有自定义的属性,可以使用 spring.ldap.embedded.validation.schema 来定义自定义属性类型或者对象类。

31. Caching

The Spring Framework provides support for transparently adding caching to an application. At its core, the abstraction applies caching to methods, reducing thus the number of executions based on the information available in the cache. The caching logic is applied transparently, without any interference to the invoker. Spring Boot auto-configures the cache infrastructure as long as the caching support is enabled via the @EnableCaching annotation.

[Note] Note

Check the relevant section of the Spring Framework reference for more details.

In a nutshell, adding caching to an operation of your service is as easy as adding the relevant annotation to its method:

import org.springframework.cache.annotation.Cacheable
import org.springframework.stereotype.Component;

@Component
public class MathService {

    @Cacheable("piDecimals")
    public int computePiDecimal(int i) {
        // ...
    }

}

This example demonstrates the use of caching on a potentially costly operation. Before invoking computePiDecimal, the abstraction will look for an entry in the piDecimals cache matching the i argument. If an entry is found, the content in the cache is immediately returned to the caller and the method is not invoked. Otherwise, the method is invoked and the cache is updated before returning the value.

[Note] Note

You can also use the standard JSR-107 (JCache) annotations (e.g. @CacheResult) transparently. We strongly advise you however to not mix and match them.

If you do not add any specific cache library, Spring Boot will auto-configure a Simple provider that uses concurrent maps in memory. When a cache is required (i.e. piDecimals in the example above), this provider will create it on-the-fly for you. The simple provider is not really recommended for production usage, but it�s great for getting started and making sure that you understand the features. When you have made up your mind about the cache provider to use, please make sure to read its documentation to figure out how to configure the caches that your application uses. Practically all providers require you to explicitly configure every cache that you use in the application. Some offer a way to customize the default caches defined by the spring.cache.cache-names property.

[Tip] Tip

It is also possible to update or evict data from the cache transparently.

[Note] Note

If you are using the cache infrastructure with beans that are not interface-based, make sure to enable the proxyTargetClass attribute of @EnableCaching.

31.1 Supported cache providers

The cache abstraction does not provide an actual store and relies on abstraction materialized by the org.springframework.cache.Cache and org.springframework.cache.CacheManager interfaces.

If you haven�t defined a bean of type CacheManager or a CacheResolver named cacheResolver (see CachingConfigurer), Spring Boot tries to detect the following providers (in this order):

[Tip] Tip

It is also possible to force the cache provider to use via the spring.cache.type property. Use this property if you need to disable caching altogether in certain environment (e.g. tests).

[Tip] Tip

Use the spring-boot-starter-cache �Starter� to quickly add basic caching dependencies. The starter brings in spring-context-support: if you are adding dependencies manually, you must include spring-context-support in order to use the JCache, EhCache 2.x or Guava support.

If the CacheManager is auto-configured by Spring Boot, you can further tune its configuration before it is fully initialized by exposing a bean implementing the CacheManagerCustomizer interface. The following sets a flag to say that null values should be passed down to the underlying map.

@Bean
public CacheManagerCustomizer<ConcurrentMapCacheManager> cacheManagerCustomizer() {
    return new CacheManagerCustomizer<ConcurrentMapCacheManager>() {
        @Override
        public void customize(ConcurrentMapCacheManager cacheManager) {
            cacheManager.setAllowNullValues(false);
        }
    };
}
[Note] Note

In the example above, an auto-configured ConcurrentMapCacheManager is expected. If that is not the case (either you provided your own config or a different cache provider was auto-configured), the customizer won�t be invoked at all. You can have as many customizers as you want and you can also order them as usual using @Order or Ordered.

31.1.1 Generic

Generic caching is used if the context defines at least one org.springframework.cache.Cache bean. A CacheManager wrapping all beans of that type is created.

31.1.2 JCache (JSR-107)

JCache is bootstrapped via the presence of a javax.cache.spi.CachingProvider on the classpath (i.e. a JSR-107 compliant caching library) and the JCacheCacheManager provided by the spring-boot-starter-cache �Starter�. There are various compliant libraries out there and Spring Boot provides dependency management for Ehcache 3, Hazelcast and Infinispan. Any other compliant library can be added as well.

It might happen that more than one provider is present, in which case the provider must be explicitly specified. Even if the JSR-107 standard does not enforce a standardized way to define the location of the configuration file, Spring Boot does its best to accommodate with implementation details.

# Only necessary if more than one provider is present
spring.cache.jcache.provider=com.acme.MyCachingProvider
spring.cache.jcache.config=classpath:acme.xml
[Note] Note

Since a cache library may offer both a native implementation and JSR-107 support Spring Boot will prefer the JSR-107 support so that the same features are available if you switch to a different JSR-107 implementation.

[Tip] Tip

Spring Boot has a general support for Hazelcast. If a single HazelcastInstance is available, it is automatically reused for the CacheManager as well unless the spring.cache.jcache.config property is specified.

There are several ways to customize the underlying javax.cache.cacheManager:

  • Caches can be created on startup via the spring.cache.cache-names property. If a custom javax.cache.configuration.Configuration bean is defined, it is used to customize them.
  • org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer beans are invoked with the reference of the CacheManager for full customization.
[Tip] Tip

If a standard javax.cache.CacheManager bean is defined, it is wrapped automatically in a org.springframework.cache.CacheManager implementation that the abstraction expects. No further customization is applied on it.

31.1.3 EhCache 2.x

EhCache 2.x is used if a file named ehcache.xml can be found at the root of the classpath. If EhCache 2.x, the EhCacheCacheManager provided by the spring-boot-starter-cache �Starter� and such file is present it is used to bootstrap the cache manager. An alternate configuration file can be provided as well using:

spring.cache.ehcache.config=classpath:config/another-config.xml

31.1.4 Hazelcast

Spring Boot has a general support for Hazelcast. If a HazelcastInstance has been auto-configured, it is automatically wrapped in a CacheManager.

31.1.5 Infinispan

Infinispan has no default configuration file location so it must be specified explicitly (or the default bootstrap is used).

spring.cache.infinispan.config=infinispan.xml

Caches can be created on startup via the spring.cache.cache-names property. If a custom ConfigurationBuilder bean is defined, it is used to customize them.

[Note] Note

The support of Infinispan in Spring Boot is restricted to the embedded mode and is quite basic. If you want more options you should use the official Infinispan Spring Boot starter instead, check the documentation for more details.

31.1.6 Couchbase

If the Couchbase java client and the couchbase-spring-cache implementation are available and Couchbase is configured, a CouchbaseCacheManager will be auto-configured. It is also possible to create additional caches on startup using the spring.cache.cache-names property. These will operate on the Bucket that was auto-configured. You can also create additional caches on another Bucket using the customizer: assume you need two caches on the "main" Bucket (foo and bar) and one biz cache with a custom time to live of 2sec on the another Bucket. First, you can create the two first caches simply via configuration:

spring.cache.cache-names=foo,bar

Then define this extra @Configuration to configure the extra Bucket and the biz cache:

@Configuration
public class CouchbaseCacheConfiguration {

    private final Cluster cluster;

    public CouchbaseCacheConfiguration(Cluster cluster) {
        this.cluster = cluster;
    }

    @Bean
    public Bucket anotherBucket() {
        return this.cluster.openBucket("another", "secret");
    }

    @Bean
    public CacheManagerCustomizer<CouchbaseCacheManager> cacheManagerCustomizer() {
        return c -> {
            c.prepareCache("biz", CacheBuilder.newInstance(anotherBucket())
                    .withExpiration(2));
        };
    }

}

This sample configuration reuses the Cluster that was created via auto-configuration.

31.1.7 Redis

If Redis is available and configured, the RedisCacheManager is auto-configured. It is also possible to create additional caches on startup using the spring.cache.cache-names property.

[Note] Note

By default, a key prefix is added to prevent that if two separate caches use the same key, Redis would have overlapping keys and be likely to return invalid values. We strongly recommend to keep this setting enabled if you create your own RedisCacheManager.

31.1.8 Caffeine

Caffeine is a Java 8 rewrite of Guava�s cache and will supersede the Guava support in Spring Boot 2.0. If Caffeine is present, a CaffeineCacheManager (provided by the spring-boot-starter-cache �Starter�) is auto-configured. Caches can be created on startup using the spring.cache.cache-names property and customized by one of the following (in this order):

  1. A cache spec defined by spring.cache.caffeine.spec
  2. A com.github.benmanes.caffeine.cache.CaffeineSpec bean is defined
  3. A com.github.benmanes.caffeine.cache.Caffeine bean is defined

For instance, the following configuration creates a foo and bar caches with a maximum size of 500 and a time to live of 10 minutes

spring.cache.cache-names=foo,bar
                spring.cache.caffeine.spec=maximumSize=500,expireAfterAccess=600s

Besides, if a com.github.benmanes.caffeine.cache.CacheLoader bean is defined, it is automatically associated to the CaffeineCacheManager. Since the CacheLoader is going to be associated to all caches managed by the cache manager, it must be defined as CacheLoader<Object, Object>. Any other generic type will be ignored by the auto-configuration.

31.1.9 Guava (deprecated)

If Guava is present, a GuavaCacheManager is auto-configured. Caches can be created on startup using the spring.cache.cache-names property and customized by one of the following (in this order):

  1. A cache spec defined by spring.cache.guava.spec
  2. A com.google.common.cache.CacheBuilderSpec bean is defined
  3. A com.google.common.cache.CacheBuilder bean is defined

For instance, the following configuration creates a foo and bar caches with a maximum size of 500 and a time to live of 10 minutes

spring.cache.cache-names=foo,bar
                spring.cache.guava.spec=maximumSize=500,expireAfterAccess=600s

Besides, if a com.google.common.cache.CacheLoader bean is defined, it is automatically associated to the GuavaCacheManager. Since the CacheLoader is going to be associated to all caches managed by the cache manager, it must be defined as CacheLoader<Object, Object>. Any other generic type will be ignored by the auto-configuration.

31.1.10 Simple

If none of the other providers can be found, a simple implementation using a ConcurrentHashMap as cache store is configured. This is the default if no caching library is present in your application. Caches are created on-the-fly by default but you can restrict the list of available caches using the cache-names property. For instance, if you want only foo and bar caches:

spring.cache.cache-names=foo,bar

If you do this and your application uses a cache not listed then it will fail at runtime when the cache is needed, but not on startup. This is similar to the way the "real" cache providers behave if you use an undeclared cache.

31.1.11 None

When @EnableCaching is present in your configuration, a suitable cache configuration is expected as well. If you need to disable caching altogether in certain environments, force the cache type to none to use a no-op implementation:

spring.cache.type=none

32. Messaging

The Spring Framework provides extensive support for integrating with messaging systems: from simplified use of the JMS API using JmsTemplate to a complete infrastructure to receive messages asynchronously. Spring AMQP provides a similar feature set for the �Advanced Message Queuing Protocol� and Spring Boot also provides auto-configuration options for RabbitTemplate and RabbitMQ. There is also support for STOMP messaging natively in Spring WebSocket and Spring Boot has support for that through starters and a small amount of auto-configuration. Spring Boot also has support for Apache Kafka.

32.1 JMS

The javax.jms.ConnectionFactory interface provides a standard method of creating a javax.jms.Connection for interacting with a JMS broker. Although Spring needs a ConnectionFactory to work with JMS, you generally won�t need to use it directly yourself and you can instead rely on higher level messaging abstractions (see the relevant section of the Spring Framework reference documentation for details). Spring Boot also auto-configures the necessary infrastructure to send and receive messages.

32.1.1 ActiveMQ support

Spring Boot can also configure a ConnectionFactory when it detects that ActiveMQ is available on the classpath. If the broker is present, an embedded broker is started and configured automatically (as long as no broker URL is specified through configuration).

[Note] Note

If you are using spring-boot-starter-activemq the necessary dependencies to connect or embed an ActiveMQ instance are provided, as well as the Spring infrastructure to integrate with JMS.

ActiveMQ configuration is controlled by external configuration properties in spring.activemq.*. For example, you might declare the following section in application.properties:

spring.activemq.broker-url=tcp://192.168.1.210:9876
spring.activemq.user=admin
spring.activemq.password=secret

You can also pool JMS resources by adding a dependency to org.apache.activemq:activemq-pool and configure the PooledConnectionFactory accordingly:

spring.activemq.pool.enabled=true
spring.activemq.pool.max-connections=50

See ActiveMQProperties for more of the supported options.

By default, ActiveMQ creates a destination if it does not exist yet, so destinations are resolved against their provided names.

32.1.2 Artemis support

Spring Boot can auto-configure a ConnectionFactory when it detects that Artemis is available on the classpath. If the broker is present, an embedded broker is started and configured automatically (unless the mode property has been explicitly set). The supported modes are: embedded (to make explicit that an embedded broker is required and should lead to an error if the broker is not available in the classpath), and native to connect to a broker using the netty transport protocol. When the latter is configured, Spring Boot configures a ConnectionFactory connecting to a broker running on the local machine with the default settings.

[Note] Note

If you are using spring-boot-starter-artemis the necessary dependencies to connect to an existing Artemis instance are provided, as well as the Spring infrastructure to integrate with JMS. Adding org.apache.activemq:artemis-jms-server to your application allows you to use the embedded mode.

Artemis configuration is controlled by external configuration properties in spring.artemis.*. For example, you might declare the following section in application.properties:

spring.artemis.mode=native
spring.artemis.host=192.168.1.210
spring.artemis.port=9876
spring.artemis.user=admin
spring.artemis.password=secret

When embedding the broker, you can choose if you want to enable persistence, and the list of destinations that should be made available. These can be specified as a comma-separated list to create them with the default options; or you can define bean(s) of type org.apache.activemq.artemis.jms.server.config.JMSQueueConfiguration or org.apache.activemq.artemis.jms.server.config.TopicConfiguration, for advanced queue and topic configurations respectively.

See ArtemisProperties for more of the supported options.

No JNDI lookup is involved at all and destinations are resolved against their names, either using the �name� attribute in the Artemis configuration or the names provided through configuration.

32.1.3 Using a JNDI ConnectionFactory

If you are running your application in an Application Server Spring Boot will attempt to locate a JMS ConnectionFactory using JNDI. By default the locations java:/JmsXA and java:/XAConnectionFactory will be checked. You can use the spring.jms.jndi-name property if you need to specify an alternative location:

spring.jms.jndi-name=java:/MyConnectionFactory

32.1.4 Sending a message

Spring�s JmsTemplate is auto-configured and you can autowire it directly into your own beans:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

    private final JmsTemplate jmsTemplate;

    @Autowired
    public MyBean(JmsTemplate jmsTemplate) {
        this.jmsTemplate = jmsTemplate;
    }

    // ...

}
[Note] Note

JmsMessagingTemplate can be injected in a similar manner. If a DestinationResolver or MessageConverter beans are defined, they are associated automatically to the auto-configured JmsTemplate.

32.1.5 Receiving a message

When the JMS infrastructure is present, any bean can be annotated with @JmsListener to create a listener endpoint. If no JmsListenerContainerFactory has been defined, a default one is configured automatically. If a DestinationResolver or MessageConverter beans are defined, they are associated automatically to the default factory.

The default factory is transactional by default. If you are running in an infrastructure where a JtaTransactionManager is present, it will be associated to the listener container by default. If not, the sessionTransacted flag will be enabled. In that latter scenario, you can associate your local data store transaction to the processing of an incoming message by adding @Transactional on your listener method (or a delegate thereof). This will make sure that the incoming message is acknowledged once the local transaction has completed. This also includes sending response messages that have been performed on the same JMS session.

The following component creates a listener endpoint on the someQueue destination:

@Component
                        public class MyBean {

                        @JmsListener(destination = "someQueue")
                        public void processMessage(String content) {
                        // ... } }

                        
[Tip] Tip

Check the Javadoc of @EnableJms for more details.

If you need to create more JmsListenerContainerFactory instances or if you want to override the default, Spring Boot provides a DefaultJmsListenerContainerFactoryConfigurer that you can use to initialize a DefaultJmsListenerContainerFactory with the same settings as the one that is auto-configured.

For instance, the following exposes another factory that uses a specific MessageConverter:

@Configuration
static class JmsConfiguration {

    @Bean
    public DefaultJmsListenerContainerFactory myFactory(
            DefaultJmsListenerContainerFactoryConfigurer configurer) {
        DefaultJmsListenerContainerFactory factory =
                new DefaultJmsListenerContainerFactory();
        configurer.configure(factory, connectionFactory());
        factory.setMessageConverter(myMessageConverter());
        return factory;
    }

}

Then you can use in any @JmsListener-annotated method as follows:

@Component
                            public class MyBean { @JmsListener(destination = "someQueue", containerFactory="myFactory")
                            public void processMessage(String content) {
                            // ... } }

                            

32.2 AMQP

The Advanced Message Queuing Protocol (AMQP) is a platform-neutral, wire-level protocol for message-oriented middleware. The Spring AMQP project applies core Spring concepts to the development of AMQP-based messaging solutions. Spring Boot offers several conveniences for working with AMQP via RabbitMQ, including the spring-boot-starter-amqp �Starter�.

32.2.1 RabbitMQ support

RabbitMQ is a lightweight, reliable, scalable and portable message broker based on the AMQP protocol. Spring uses RabbitMQ to communicate using the AMQP protocol.

RabbitMQ configuration is controlled by external configuration properties in spring.rabbitmq.*. For example, you might declare the following section in application.properties:

spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=admin
spring.rabbitmq.password=secret

See RabbitProperties for more of the supported options.

32.2.2 Sending a message

Spring�s AmqpTemplate and AmqpAdmin are auto-configured and you can autowire them directly into your own beans:

import org.springframework.amqp.core.AmqpAdmin;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MyBean {

    private final AmqpAdmin amqpAdmin;
    private final AmqpTemplate amqpTemplate;

    @Autowired
    public MyBean(AmqpAdmin amqpAdmin, AmqpTemplate amqpTemplate) {
        this.amqpAdmin = amqpAdmin;
        this.amqpTemplate = amqpTemplate;
    }

    // ...

}
[Note] Note

RabbitMessagingTemplate can be injected in a similar manner. If a MessageConverter bean is defined, it is associated automatically to the auto-configured AmqpTemplate.

Any org.springframework.amqp.core.Queue that is defined as a bean will be automatically used to declare a corresponding queue on the RabbitMQ instance if necessary.

You can enable retries on the AmqpTemplate to retry operations, for example in the event the broker connection is lost. Retries are disabled by default.

32.2.3 Receiving a message

When the Rabbit infrastructure is present, any bean can be annotated with @RabbitListener to create a listener endpoint. If no RabbitListenerContainerFactory has been defined, a default one is configured automatically. If a MessageConverter or MessageRecoverer beans are defined, they are associated automatically to the default factory.

The following component creates a listener endpoint on the someQueue queue:

@Component
                    public class MyBean {

                    @RabbitListener(queues = "someQueue")
                    public void processMessage(String content) {
                    // ... } }

                    
[Tip] Tip

Check the Javadoc of @EnableRabbit for more details.

If you need to create more RabbitListenerContainerFactory instances or if you want to override the default, Spring Boot provides a SimpleRabbitListenerContainerFactoryConfigurer that you can use to initialize a SimpleRabbitListenerContainerFactory with the same settings as the one that is auto-configured.

For instance, the following exposes another factory that uses a specific MessageConverter:

@Configuration
static class RabbitConfiguration {

    @Bean
    public SimpleRabbitListenerContainerFactory myFactory(
            SimpleRabbitListenerContainerFactoryConfigurer configurer) {
        SimpleRabbitListenerContainerFactory factory =
                new SimpleRabbitListenerContainerFactory();
        configurer.configure(factory, connectionFactory);
        factory.setMessageConverter(myMessageConverter());
        return factory;
    }

}

Then you can use in any @RabbitListener-annotated method as follows:

@Component
                        public class MyBean { @RabbitListener(queues = "someQueue", containerFactory="myFactory")
                        public void processMessage(String content) {
                        // ... } }

                        

You can enable retries to handle situations where your listener throws an exception. By default RejectAndDontRequeueRecoverer is used but you can define a MessageRecoverer of your own. When retries are exhausted, the message will be rejected and either dropped or routed to a dead-letter exchange if the broker is configured so. Retries are disabled by default.

[Important] Important

If retries are not enabled and the listener throws an exception, by default the delivery will be retried indefinitely. You can modify this behavior in two ways; set the defaultRequeueRejected property to false and zero re-deliveries will be attempted; or, throw an AmqpRejectAndDontRequeueException to signal the message should be rejected. This is the mechanism used when retries are enabled and the maximum delivery attempts are reached.

32.3 Apache Kafka Support

Apache Kafka is supported by providing auto-configuration of the spring-kafka project.

Kafka configuration is controlled by external configuration properties in spring.kafka.*. For example, you might declare the following section in application.properties:

spring.kafka.bootstrap-servers=localhost:9092
spring.kafka.consumer.group-id=myGroup

See KafkaProperties for more of the supported options.

32.3.1 Sending a Message

Spring�s KafkaTemplate is auto-configured and you can autowire them directly in your own beans:

@Component
public class MyBean {

	private final KafkaTemplate kafkaTemplate;

	@Autowired
	public MyBean(KafkaTemplate kafkaTemplate) {
		this.kafkaTemplate = kafkaTemplate;
	}

	// ...

}

32.3.2 Receiving a Message

When the Apache Kafka infrastructure is present, any bean can be annotated with @KafkaListener to create a listener endpoint. If no KafkaListenerContainerFactory has been defined, a default one is configured automatically with keys defined in spring.kafka.listener.*.

The following component creates a listener endpoint on the someTopic topic:

@Component
                public class MyBean {

                @KafkaListener(topics = "someTopic")
                public void processMessage(String content) {
                // ... } }

                

32.3.3 Additional Kafka Properties

The properties supported by auto configuration are shown in Appendix A, Common application properties. Note that these properties (hyphenated or camelCase) map directly to the Apache Kafka dotted properties for the most part, refer to the Apache Kafka documentation for details.

The first few of these properties apply to both producers and consumers, but can be specified at the producer or consumer level if you wish to use different values for each. Apache Kafka designates properties with an importance: HIGH, MEDIUM and LOW. Spring Boot auto configuration supports all HIGH importance properties, some selected MEDIUM and LOW, and any that do not have a default value.

Only a subset of the properties supported by Kafka are available via the KafkaProperties class. If you wish to configure the producer or consumer with additional properties that are not directly supported, use the following:

spring.kafka.properties.foo.bar=baz

This sets the common foo.bar Kafka property to baz.

These properties will be shared by both the consumer and producer factory beans. If you wish to customize these components with different properties, such as to use a different metrics reader for each, you can override the bean definitions, as follows:

@Configuration
public static class CustomKafkaBeans {

    /**
     * Customized ProducerFactory bean.
     * @param properties the kafka properties.
     * @return the bean.
     */
    @Bean
    public ProducerFactory<?, ?> kafkaProducerFactory(KafkaProperties properties) {
        Map<String, Object> producerProperties = properties.buildProducerProperties();
        producerProperties.put(CommonClientConfigs.METRIC_REPORTER_CLASSES_CONFIG,
                MyProducerMetricsReporter.class);
        return new DefaultKafkaProducerFactory<Object, Object>(producerProperties);
    }

    /**
     * Customized ConsumerFactory bean.
     * @param properties the kafka properties.
     * @return the bean.
     */
    @Bean
    public ConsumerFactory<?, ?> kafkaConsumerFactory(KafkaProperties properties) {
        Map<String, Object> consumerProperties = properties.buildConsumerProperties();
        consumerProperties.put(CommonClientConfigs.METRIC_REPORTER_CLASSES_CONFIG,
                MyConsumerMetricsReporter.class);
        return new DefaultKafkaConsumerFactory<Object, Object>(consumerProperties);
    }

}

33. Calling REST services

If you need to call remote REST services from your application, you can use Spring Framework�s RestTemplate class. Since RestTemplate instances often need to be customized before being used, Spring Boot does not provide any single auto-configured RestTemplate bean. It does, however, auto-configure a RestTemplateBuilder which can be used to create RestTemplate instances when needed. The auto-configured RestTemplateBuilder will ensure that sensible HttpMessageConverters are applied to RestTemplate instances.

Here�s a typical example:

@Service
public class MyBean {

    private final RestTemplate restTemplate;

    public MyBean(RestTemplateBuilder restTemplateBuilder) {
        this.restTemplate = restTemplateBuilder.build();
    }

    public Details someRestCall(String name) {
        return this.restTemplate.getForObject("/{name}/details", Details.class, name);
    }

}
[Tip] Tip

RestTemplateBuilder includes a number of useful methods that can be used to quickly configure a RestTemplate. For example, to add BASIC auth support you can use builder.basicAuthorization("user", "password").build().

33.1 RestTemplate customization

There are three main approaches to RestTemplate customization, depending on how broadly you want the customizations to apply.

To make the scope of any customizations as narrow as possible, inject the auto-configured RestTemplateBuilder and then call its methods as required. Each method call returns a new RestTemplateBuilder instance so the customizations will only affect this use of the builder.

To make an application-wide, additive customization a RestTemplateCustomizer bean can be used. All such beans are automatically registered with the auto-configured RestTemplateBuilder and will be applied to any templates that are built with it.

Here�s an example of a customizer that configures the use of a proxy for all hosts except 192.168.0.5:

static class ProxyCustomizer implements RestTemplateCustomizer {

    @Override
    public void customize(RestTemplate restTemplate) {
        HttpHost proxy = new HttpHost("proxy.example.com");
        HttpClient httpClient = HttpClientBuilder.create()
                .setRoutePlanner(new DefaultProxyRoutePlanner(proxy) {

                    @Override
                    public HttpHost determineProxy(HttpHost target,
                            HttpRequest request, HttpContext context)
                                    throws HttpException {
                        if (target.getHostName().equals("192.168.0.5")) {
                            return null;
                        }
                        return super.determineProxy(target, request, context);
                    }

                }).build();
        restTemplate.setRequestFactory(
                new HttpComponentsClientHttpRequestFactory(httpClient));
    }

}

Lastly, the most extreme (and rarely used) option is to create your own RestTemplateBuilder bean. This will switch off the auto-configuration of a RestTemplateBuilder and will prevent any RestTemplateCustomizer beans from being used.

34. Validation

The method validation feature supported by Bean Validation 1.1 is automatically enabled as long as a JSR-303 implementation (e.g. Hibernate validator) is on the classpath. This allows bean methods to be annotated with javax.validation constraints on their parameters and/or on their return value. Target classes with such annotated methods need to be annotated with the @Validated annotation at the type level for their methods to be searched for inline constraint annotations.

For instance, the following service triggers the validation of the first argument, making sure its size is between 8 and 10

@Service
@Validated
public class MyBean {

    public Archive findByCodeAndAuthor(@Size(min = 8, max = 10) String code,
            Author author) {
        ...
    }

}

35. Sending email

The Spring Framework provides an easy abstraction for sending email using the JavaMailSender interface and Spring Boot provides auto-configuration for it as well as a starter module.

[Tip] Tip

Check the reference documentation for a detailed explanation of how you can use JavaMailSender.

If spring.mail.host and the relevant libraries (as defined by spring-boot-starter-mail) are available, a default JavaMailSender is created if none exists. The sender can be further customized by configuration items from the spring.mail namespace, see the MailProperties for more details.

In particular, certain default timeout values are infinite and you may want to change that to avoid having a thread blocked by an unresponsive mail server:

spring.mail.properties.mail.smtp.connectiontimeout=5000
spring.mail.properties.mail.smtp.timeout=3000
spring.mail.properties.mail.smtp.writetimeout=5000

36. Distributed Transactions with JTA

Spring Boot supports distributed JTA transactions across multiple XA resources using either an Atomikos or Bitronix embedded transaction manager. JTA transactions are also supported when deploying to a suitable Java EE Application Server.

When a JTA environment is detected, Spring�s JtaTransactionManager will be used to manage transactions. Auto-configured JMS, DataSource and JPA beans will be upgraded to support XA transactions. You can use standard Spring idioms such as @Transactional to participate in a distributed transaction. If you are within a JTA environment and still want to use local transactions you can set the spring.jta.enabled property to false to disable the JTA auto-configuration.

36.1 Using an Atomikos transaction manager

Atomikos is a popular open source transaction manager which can be embedded into your Spring Boot application. You can use the spring-boot-starter-jta-atomikos Starter to pull in the appropriate Atomikos libraries. Spring Boot will auto-configure Atomikos and ensure that appropriate depends-on settings are applied to your Spring beans for correct startup and shutdown ordering.

By default Atomikos transaction logs will be written to a transaction-logs directory in your application home directory (the directory in which your application jar file resides). You can customize this directory by setting a spring.jta.log-dir property in your application.properties file. Properties starting spring.jta.atomikos.properties can also be used to customize the Atomikos UserTransactionServiceImp. See the AtomikosProperties Javadoc for complete details.

[Note] Note

To ensure that multiple transaction managers can safely coordinate the same resource managers, each Atomikos instance must be configured with a unique ID. By default this ID is the IP address of the machine on which Atomikos is running. To ensure uniqueness in production, you should configure the spring.jta.transaction-manager-id property with a different value for each instance of your application.

36.2 Using a Bitronix transaction manager

Bitronix is popular open source JTA transaction manager implementation. You can use the spring-boot-starter-jta-bitronix starter to add the appropriate Bitronix dependencies to your project. As with Atomikos, Spring Boot will automatically configure Bitronix and post-process your beans to ensure that startup and shutdown ordering is correct.

By default Bitronix transaction log files (part1.btm and part2.btm) will be written to a transaction-logs directory in your application home directory. You can customize this directory by using the spring.jta.log-dir property. Properties starting spring.jta.bitronix.properties are also bound to the bitronix.tm.Configuration bean, allowing for complete customization. See the Bitronix documentation for details.

[Note] Note

To ensure that multiple transaction managers can safely coordinate the same resource managers, each Bitronix instance must be configured with a unique ID. By default this ID is the IP address of the machine on which Bitronix is running. To ensure uniqueness in production, you should configure the spring.jta.transaction-manager-id property with a different value for each instance of your application.

36.3 Using a Narayana transaction manager

Narayana is popular open source JTA transaction manager implementation supported by JBoss. You can use the spring-boot-starter-jta-narayana starter to add the appropriate Narayana dependencies to your project. As with Atomikos and Bitronix, Spring Boot will automatically configure Narayana and post-process your beans to ensure that startup and shutdown ordering is correct.

By default Narayana transaction logs will be written to a transaction-logs directory in your application home directory (the directory in which your application jar file resides). You can customize this directory by setting a spring.jta.log-dir property in your application.properties file. Properties starting spring.jta.narayana.properties can also be used to customize the Narayana configuration. See the NarayanaProperties Javadoc for complete details.

[Note] Note

To ensure that multiple transaction managers can safely coordinate the same resource managers, each Narayana instance must be configured with a unique ID. By default this ID is set to 1. To ensure uniqueness in production, you should configure the spring.jta.transaction-manager-id property with a different value for each instance of your application.

36.4 Using a Java EE managed transaction manager

If you are packaging your Spring Boot application as a war or ear file and deploying it to a Java EE application server, you can use your application servers built-in transaction manager. Spring Boot will attempt to auto-configure a transaction manager by looking at common JNDI locations (java:comp/UserTransaction, java:comp/TransactionManager etc). If you are using a transaction service provided by your application server, you will generally also want to ensure that all resources are managed by the server and exposed over JNDI. Spring Boot will attempt to auto-configure JMS by looking for a ConnectionFactory at the JNDI path java:/JmsXA or java:/XAConnectionFactory and you can use the spring.datasource.jndi-name property to configure your DataSource.

36.5 Mixing XA and non-XA JMS connections

When using JTA, the primary JMS ConnectionFactory bean will be XA aware and participate in distributed transactions. In some situations you might want to process certain JMS messages using a non-XA ConnectionFactory. For example, your JMS processing logic might take longer than the XA timeout.

If you want to use a non-XA ConnectionFactory you can inject the nonXaJmsConnectionFactory bean rather than the @Primary jmsConnectionFactory bean. For consistency the jmsConnectionFactory bean is also provided using the bean alias xaJmsConnectionFactory.

For example:

// Inject the primary (XA aware) ConnectionFactory
@Autowired
private ConnectionFactory defaultConnectionFactory;

// Inject the XA aware ConnectionFactory (uses the alias and injects the same as above)
@Autowired
@Qualifier("xaJmsConnectionFactory")
private ConnectionFactory xaConnectionFactory;

// Inject the non-XA aware ConnectionFactory
@Autowired
@Qualifier("nonXaJmsConnectionFactory")
private ConnectionFactory nonXaConnectionFactory;

36.6 Supporting an alternative embedded transaction manager

The XAConnectionFactoryWrapper and XADataSourceWrapper interfaces can be used to support alternative embedded transaction managers. The interfaces are responsible for wrapping XAConnectionFactory and XADataSource beans and exposing them as regular ConnectionFactory and DataSource beans which will transparently enroll in the distributed transaction. DataSource and JMS auto-configuration will use JTA variants as long as you have a JtaTransactionManager bean and appropriate XA wrapper beans registered within your ApplicationContext.

The BitronixXAConnectionFactoryWrapper and BitronixXADataSourceWrapper provide good examples of how to write XA wrappers.

37. Hazelcast

If hazelcast is on the classpath, Spring Boot will auto-configure an HazelcastInstance that you can inject in your application. The HazelcastInstance is only created if a configuration is found.

You can define a com.hazelcast.config.Config bean and we�ll use that. If your configuration defines an instance name, we�ll try to locate an existing instance rather than creating a new one.

You could also specify the hazelcast.xml configuration file to use via configuration:

spring.hazelcast.config=classpath:config/my-hazelcast.xml

Otherwise, Spring Boot tries to find the Hazelcast configuration from the default locations, that is hazelcast.xml in the working directory or at the root of the classpath. We also check if the hazelcast.config system property is set. Check the Hazelcast documentation for more details.

[Note] Note

Spring Boot also has an explicit caching support for Hazelcast. The HazelcastInstance is automatically wrapped in a CacheManager implementation if caching is enabled.

38. Spring Integration

Spring Boot offers several conveniences for working with Spring Integration, including the spring-boot-starter-integration �Starter�. Spring Integration provides abstractions over messaging and also other transports such as HTTP, TCP etc. If Spring Integration is available on your classpath it will be initialized through the @EnableIntegration annotation. Message processing statistics will be published over JMX if 'spring-integration-jmx' is also on the classpath. See the IntegrationAutoConfiguration class for more details.

39. Spring Session

Spring Boot provides Spring Session auto-configuration for a wide range of stores:

  • JDBC
  • MongoDB
  • Redis
  • Hazelcast
  • HashMap

If Spring Session is available, you must choose the StoreType that you wish to use to store the sessions. For instance to use JDBC as backend store, you�d configure your application as follows:

spring.session.store-type=jdbc
[Tip] Tip

You can disable Spring Session by setting the store-type to none.

Each store has specific additional settings. For instance it is possible to customize the name of the table for the jdbc store:

spring.session.jdbc.table-name=SESSIONS

40. Monitoring and management over JMX

Java Management Extensions (JMX) provide a standard mechanism to monitor and manage applications. By default Spring Boot will create an MBeanServer with bean id �mbeanServer� and expose any of your beans that are annotated with Spring JMX annotations (@ManagedResource, @ManagedAttribute, @ManagedOperation).

See the JmxAutoConfiguration class for more details.

41. Testing

Spring Boot provides a number of utilities and annotations to help when testing your application. Test support is provided by two modules; spring-boot-test contains core items, and spring-boot-test-autoconfigure supports auto-configuration for tests.

Most developers will just use the spring-boot-starter-test �Starter� which imports both Spring Boot test modules as well has JUnit, AssertJ, Hamcrest and a number of other useful libraries.

41.1 Test scope dependencies

If you use the spring-boot-starter-test �Starter� (in the test scope), you will find the following provided libraries:

  • JUnit � The de-facto standard for unit testing Java applications.
  • Spring Test & Spring Boot Test � Utilities and integration test support for Spring Boot applications.
  • AssertJ � A fluent assertion library.
  • Hamcrest � A library of matcher objects (also known as constraints or predicates).
  • Mockito � A Java mocking framework.
  • JSONassert � An assertion library for JSON.
  • JsonPath � XPath for JSON.
[Note] Note

By default, Spring Boot uses Mockito 1.x. However it�s also possible to use 2.x if you wish.

These are common libraries that we generally find useful when writing tests. You are free to add additional test dependencies of your own if these don�t suit your needs.

41.2 Testing Spring applications

One of the major advantages of dependency injection is that it should make your code easier to unit test. You can simply instantiate objects using the new operator without even involving Spring. You can also use mock objects instead of real dependencies.

Often you need to move beyond �unit testing� and start �integration testing� (with a Spring ApplicationContext actually involved in the process). It�s useful to be able to perform integration testing without requiring deployment of your application or needing to connect to other infrastructure.

The Spring Framework includes a dedicated test module for just such integration testing. You can declare a dependency directly to org.springframework:spring-test or use the spring-boot-starter-test �Starter� to pull it in transitively.

If you have not used the spring-test module before you should start by reading the relevant section of the Spring Framework reference documentation.

41.3 Testing Spring Boot applications

A Spring Boot application is just a Spring ApplicationContext, so nothing very special has to be done to test it beyond what you would normally do with a vanilla Spring context. One thing to watch out for though is that the external properties, logging and other features of Spring Boot are only installed in the context by default if you use SpringApplication to create it.

Spring Boot provides a @SpringBootTest annotation which can be used as an alternative to the standard spring-test @ContextConfiguration annotation when you need Spring Boot features. The annotation works by creating the ApplicationContext used in your tests via SpringApplication.

You can use the webEnvironment attribute of @SpringBootTest to further refine how your tests will run:

  • MOCK � Loads a WebApplicationContext and provides a mock servlet environment. Embedded servlet containers are not started when using this annotation. If servlet APIs are not on your classpath this mode will transparently fallback to creating a regular non-web ApplicationContext. Can be used in conjunction with @AutoConfigureMockMvc for MockMvc-based testing of your application.
  • RANDOM_PORT � Loads an EmbeddedWebApplicationContext and provides a real servlet environment. Embedded servlet containers are started and listening on a random port.
  • DEFINED_PORT � Loads an EmbeddedWebApplicationContext and provides a real servlet environment. Embedded servlet containers are started and listening on a defined port (i.e from your application.properties or on the default port 8080).
  • NONE � Loads an ApplicationContext using SpringApplication but does not provide any servlet environment (mock or otherwise).
[Note] Note

If your test is @Transactional, it will rollback the transaction at the end of each test method by default. If you�re using this arrangement in combination with either RANDOM_PORT or DEFINED_PORT, any transaction initiated on the server won�t rollback as the test is running in a different thread than the server processing.

[Note] Note

In addition to @SpringBootTest a number of other annotations are also provided for testing more specific slices of an application. See below for details.

[Tip] Tip

Don�t forget to also add @RunWith(SpringRunner.class) to your test, otherwise the annotations will be ignored.

41.3.1 Detecting test configuration

If you�re familiar with the Spring Test Framework, you may be used to using @ContextConfiguration(classes=�​) in order to specify which Spring @Configuration to load. Alternatively, you might have often used nested @Configuration classes within your test.

When testing Spring Boot applications this is often not required. Spring Boot�s @*Test annotations will search for your primary configuration automatically whenever you don�t explicitly define one.

The search algorithm works up from the package that contains the test until it finds a @SpringBootApplication or @SpringBootConfiguration annotated class. As long as you�ve structured your code in a sensible way your main configuration is usually found.

If you want to customize the primary configuration, you can use a nested @TestConfiguration class. Unlike a nested @Configuration class which would be used instead of a your application�s primary configuration, a nested @TestConfiguration class will be used in addition to your application�s primary configuration.

[Note] Note

Spring�s test framework will cache application contexts between tests. Therefore, as long as your tests share the same configuration (no matter how it�s discovered), the potentially time consuming process of loading the context will only happen once.

41.3.2 Excluding test configuration

If your application uses component scanning, for example if you use @SpringBootApplication or @ComponentScan, you may find top-level configuration classes created only for specific tests accidentally get picked up everywhere.

As we have seen above, @TestConfiguration can be used on an inner class of a test to customize the primary configuration. When placed on a top-level class, @TestConfiguration indicates that classes in src/test/java should not be picked up by scanning. You can then import that class explicitly where it is required:

@RunWith(SpringRunner.class)
@SpringBootTest
@Import(MyTestsConfiguration.class)
public class MyTests {

    @Test
    public void exampleTest() {
        ...
    }

}
[Note] Note

If you directly use @ComponentScan (i.e. not via @SpringBootApplication) you will need to register the TypeExcludeFilter with it. See the Javadoc for details.

41.3.3 Working with random ports

If you need to start a full running server for tests, we recommend that you use random ports. If you use @SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT) an available port will be picked at random each time your test runs.

The @LocalServerPort annotation can be used to inject the actual port used into your test. For convenience, tests that need to make REST calls to the started server can additionally @Autowire a TestRestTemplate which will resolve relative links to the running server.

import org.junit.Test;
import org.junit.runner.RunWith;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.test.context.junit4.SpringRunner;

import static org.assertj.core.api.Assertions.assertThat;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class RandomPortExampleTests {

	@Autowired
	private TestRestTemplate restTemplate;

	@Test
	public void exampleTest() {
		String body = this.restTemplate.getForObject("/", String.class);
		assertThat(body).isEqualTo("Hello World");
	}

}

41.3.4 Mocking and spying beans

It�s sometimes necessary to mock certain components within your application context when running tests. For example, you may have a facade over some remote service that�s unavailable during development. Mocking can also be useful when you want to simulate failures that might be hard to trigger in a real environment.

Spring Boot includes a @MockBean annotation that can be used to define a Mockito mock for a bean inside your ApplicationContext. You can use the annotation to add new beans, or replace a single existing bean definition. The annotation can be used directly on test classes, on fields within your test, or on @Configuration classes and fields. When used on a field, the instance of the created mock will also be injected. Mock beans are automatically reset after each test method.

Here�s a typical example where we replace an existing RemoteService bean with a mock implementation:

import org.junit.*;
import org.junit.runner.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.boot.test.context.*;
import org.springframework.boot.test.mock.mockito.*;
import org.springframework.test.context.junit4.*;

import static org.assertj.core.api.Assertions.*;
import static org.mockito.BDDMockito.*;

@RunWith(SpringRunner.class)
@SpringBootTest
public class MyTests {

    @MockBean
    private RemoteService remoteService;

    @Autowired
    private Reverser reverser;

    @Test
    public void exampleTest() {
        // RemoteService has been injected into the reverser bean
        given(this.remoteService.someCall()).willReturn("mock");
        String reverse = reverser.reverseSomeCall();
        assertThat(reverse).isEqualTo("kcom");
    }

}

Additionally you can also use @SpyBean to wrap any existing bean with a Mockito spy. See the Javadoc for full details.

41.3.5 Auto-configured tests

Spring Boot�s auto-configuration system works well for applications, but can sometimes be a little too much for tests. It�s often helpful to load only the parts of the configuration that are required to test a �slice� of your application. For example, you might want to test that Spring MVC controllers are mapping URLs correctly, and you don�t want to involve database calls in those tests; or you might be wanting to test JPA entities, and you�re not interested in web layer when those tests run.

The spring-boot-test-autoconfigure module includes a number of annotations that can be used to automatically configure such �slices�. Each of them works in a similar way, providing a @�​Test annotation that loads the ApplicationContext and one or more @AutoConfigure�​ annotations that can be used to customize auto-configuration settings.

[Note] Note

Each slice loads a very restricted set of auto-configuration classes. If you need to exclude one of them, most @�​Test annotations provide an excludeAutoConfiguration attribute. Alternatively, you can use @ImportAutoConfiguration#exclude.

[Tip] Tip

It�s also possible to use the @AutoConfigure�​ annotations with the standard @SpringBootTest annotation. You can use this combination if you�re not interested in �slicing� your application but you want some of the auto-configured test beans.

41.3.6 Auto-configured JSON tests

To test that Object JSON serialization and deserialization is working as expected you can use the @JsonTest annotation. @JsonTest will auto-configure Jackson ObjectMapper, any @JsonComponent beans and any Jackson Modules. It also configures Gson if you happen to be using that instead of, or as well as, Jackson. If you need to configure elements of the auto-configuration you can use the @AutoConfigureJsonTesters annotation.

Spring Boot includes AssertJ based helpers that work with the JSONassert and JsonPath libraries to check that JSON is as expected. The JacksonTester, GsonTester and BasicJsonTester classes can be used for Jackson, Gson and Strings respectively. Any helper fields on the test class can be @Autowired when using @JsonTest.

import org.junit.*;
                    import org.junit.runner.*;
                    import org.springframework.beans.factory.annotation.*;
                    import org.springframework.boot.test.autoconfigure.json.*;
                    import org.springframework.boot.test.context.*;
                    import org.springframework.boot.test.json.*;
                    import org.springframework.test.context.junit4.*;

                    import static org.assertj.core.api.Assertions.*;

                    @RunWith(SpringRunner.class)
                    @JsonTest
                    public class MyJsonTests {

                    @Autowired
                    private JacksonTester<VehicleDetails>
                    json;

                    @Test
                    public void testSerialize() throws                    Exception { VehicleDetails details = new                    VehicleDetails("Honda",
                    "Civic");
                        // Assert against a `.json` file in the same package as the test                        assertThat(
                        this.json.write(details)).isEqualToJson(
                        "expected.json");
                            // Or use JSON path based assertions                            assertThat(
                            this.json.write(details)).hasJsonPathStringValue(
                            "@.make"); assertThat(
                                this.json.write(details)).extractingJsonPathStringValue(
                                "@.make") .isEqualTo(
                                    "Honda"); }

                                    @Test
                                    public
                                    void testDeserialize() throws                                        Exception { String content = "{\"make\":\"Ford\",\"model\":\"Focus\"}";
                                        assertThat(
                                        this.json.parse(content))
                                        .isEqualTo(
                                        new VehicleDetails(
                                        "Ford", "Focus"));
                                            assertThat(
                                            this.json.parseObject(content).getMake()).isEqualTo(
                                            "Ford"); } }

                                                
[Note] Note

JSON helper classes can also be used directly in standard unit tests. Simply call the initFields method of the helper in your @Before method if you aren�t using @JsonTest.

A list of the auto-configuration that is enabled by @JsonTest can be found in the appendix.

41.3.7 Auto-configured Spring MVC tests

To test Spring MVC controllers are working as expected you can use the @WebMvcTest annotation. @WebMvcTest will auto-configure the Spring MVC infrastructure and limit scanned beans to @Controller, @ControllerAdvice, @JsonComponent, Filter, WebMvcConfigurer and HandlerMethodArgumentResolver. Regular @Component beans will not be scanned when using this annotation.

Often @WebMvcTest will be limited to a single controller and used in combination with @MockBean to provide mock implementations for required collaborators.

@WebMvcTest also auto-configures MockMvc. Mock MVC offers a powerful way to quickly test MVC controllers without needing to start a full HTTP server.

[Tip] Tip

You can also auto-configure MockMvc in a non-@WebMvcTest (e.g. SpringBootTest) by annotating it with @AutoConfigureMockMvc.

import org.junit.*;
import org.junit.runner.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.boot.test.autoconfigure.web.servlet.*;
import org.springframework.boot.test.mock.mockito.*;

import static org.assertj.core.api.Assertions.*;
import static org.mockito.BDDMockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@RunWith(SpringRunner.class)
@WebMvcTest(UserVehicleController.class)
public class MyControllerTests {

    @Autowired
    private MockMvc mvc;

    @MockBean
    private UserVehicleService userVehicleService;

    @Test
    public void testExample() throws Exception {
        given(this.userVehicleService.getVehicleDetails("sboot"))
                .willReturn(new VehicleDetails("Honda", "Civic"));
        this.mvc.perform(get("/sboot/vehicle").accept(MediaType.TEXT_PLAIN))
                .andExpect(status().isOk()).andExpect(content().string("Honda Civic"));
    }

}
[Tip] Tip

If you need to configure elements of the auto-configuration (for example when servlet filters should be applied) you can use attributes in the @AutoConfigureMockMvc annotation.

If you use HtmlUnit or Selenium, auto-configuration will also provide a WebClient bean and/or a WebDriver bean. Here is an example that uses HtmlUnit:

import com.gargoylesoftware.htmlunit.*;
                import org.junit.*;
                import org.junit.runner.*;
                import org.springframework.beans.factory.annotation.*;
                import org.springframework.boot.test.autoconfigure.web.servlet.*;
                import org.springframework.boot.test.mock.mockito.*;

                import static org.assertj.core.api.Assertions.*;
                import static org.mockito.BDDMockito.*;

                @RunWith(SpringRunner.class)
                @WebMvcTest(UserVehicleController.class)
                public class MyHtmlUnitTests {

                @Autowired
                private WebClient webClient;

                @MockBean
                private UserVehicleService userVehicleService;

                @Test
                public void testExample() throws                Exception { given(
                this.userVehicleService.getVehicleDetails(
                "sboot")) .willReturn(
                    new VehicleDetails("Honda", "Civic"));
                    HtmlPage page = this.webClient.getPage(
                    "/sboot/vehicle.html"); assertThat(page.getBody().getTextContent()).isEqualTo(
                        "Honda Civic"); } }

                        
[Note] Note

By default Spring Boot will put WebDriver beans in a special �scope� to ensure that the driver is quit after each test, and that a new instance is injected. If you don�t want this behavior you can add @Scope("singleton") to your WebDriver @Bean definition.

A list of the auto-configuration that is enabled by @WebMvcTest can be found in the appendix.

41.3.8 Auto-configured Data JPA tests

@DataJpaTest can be used if you want to test JPA applications. By default it will configure an in-memory embedded database, scan for @Entity classes and configure Spring Data JPA repositories. Regular @Component beans will not be loaded into the ApplicationContext.

Data JPA tests are transactional and rollback at the end of each test by default, see the relevant section in the Spring Reference Documentation for more details. If that�s not what you want, you can disable transaction management for a test or for the whole class as follows:

import org.junit.Test;
                import org.junit.runner.RunWith;
                import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
                import org.springframework.test.context.junit4.SpringRunner;
                import org.springframework.transaction.annotation.Propagation;
                import org.springframework.transaction.annotation.Transactional;

                @RunWith(SpringRunner.class)
                @DataJpaTest
                @Transactional(propagation = Propagation.NOT_SUPPORTED)
                public class ExampleNonTransactionalTests { }

                

Data JPA tests may also inject a TestEntityManager bean which provides an alternative to the standard JPA EntityManager specifically designed for tests. If you want to use TestEntityManager outside of @DataJpaTests you can also use the @AutoConfigureTestEntityManager annotation. A JdbcTemplate is also available if you need that.

import org.junit.*;
import org.junit.runner.*;
import org.springframework.boot.test.autoconfigure.orm.jpa.*;

import static org.assertj.core.api.Assertions.*;

@RunWith(SpringRunner.class)
@DataJpaTest
public class ExampleRepositoryTests {

    @Autowired
    private TestEntityManager entityManager;

    @Autowired
    private UserRepository repository;

    @Test
    public void testExample() throws Exception {
        this.entityManager.persist(new User("sboot", "1234"));
        User user = this.repository.findByUsername("sboot");
        assertThat(user.getUsername()).isEqualTo("sboot");
        assertThat(user.getVin()).isEqualTo("1234");
    }

}

In-memory embedded databases generally work well for tests since they are fast and don�t require any developer installation. If, however, you prefer to run tests against a real database you can use the @AutoConfigureTestDatabase annotation:

@RunWith(SpringRunner.class)
@DataJpaTest
@AutoConfigureTestDatabase(replace=Replace.NONE)
public class ExampleRepositoryTests {

    // ...

}

A list of the auto-configuration that is enabled by @DataJpaTest can be found in the appendix.

41.3.9 Auto-configured JDBC tests

@JdbcTest is similar to @DataJpaTest but for pure jdbc-related tests. By default it will also configure an in-memory embedded database and a JdbcTemplate. Regular @Component beans will not be loaded into the ApplicationContext.

JDBC tests are transactional and rollback at the end of each test by default, see the relevant section in the Spring Reference Documentation for more details. If that�s not what you want, you can disable transaction management for a test or for the whole class as follows:

import org.junit.Test;
                import org.junit.runner.RunWith;
                import org.springframework.boot.test.autoconfigure.jdbc.JdbcTest;
                import org.springframework.test.context.junit4.SpringRunner;
                import org.springframework.transaction.annotation.Propagation;
                import org.springframework.transaction.annotation.Transactional;

                @RunWith(SpringRunner.class)
                @JdbcTest
                @Transactional(propagation = Propagation.NOT_SUPPORTED)
                public class ExampleNonTransactionalTests { }

                

If you prefer your test to run against a real database, you can use the @AutoConfigureTestDatabase annotation the same way as for DataJpaTest.

A list of the auto-configuration that is enabled by @JdbcTest can be found in the appendix.

41.3.10 Auto-configured Data MongoDB tests

@DataMongoTest can be used if you want to test MongoDB applications. By default, it will configure an in-memory embedded MongoDB (if available), configure a MongoTemplate, scan for @Document classes and configure Spring Data MongoDB repositories. Regular @Component beans will not be loaded into the ApplicationContext:

import org.junit.runner.RunWith;
                import org.springframework.beans.factory.annotation.Autowired;
                import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;
                import org.springframework.data.mongodb.core.MongoTemplate;
                import org.springframework.test.context.junit4.SpringRunner;

                @RunWith(SpringRunner.class)
                @DataMongoTest
                public class ExampleDataMongoTests {

                @Autowired
                private MongoTemplate mongoTemplate;

                // }
                

In-memory embedded MongoDB generally works well for tests since it is fast and doesn�t require any developer installation. If, however, you prefer to run tests against a real MongoDB server you should exclude the embedded MongoDB auto-configuration:

import org.junit.runner.RunWith;
import org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration;
import org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@DataMongoTest(excludeAutoConfiguration = EmbeddedMongoAutoConfiguration.class)
public class ExampleDataMongoNonEmbeddedTests {

}

A list of the auto-configuration that is enabled by @DataMongoTest can be found in the appendix.

41.3.11 Auto-configured REST clients

The @RestClientTest annotation can be used if you want to test REST clients. By default it will auto-configure Jackson and GSON support, configure a RestTemplateBuilder and add support for MockRestServiceServer. The specific beans that you want to test should be specified using value or components attribute of @RestClientTest:

@RunWith(SpringRunner.class)
@RestClientTest(RemoteVehicleDetailsService.class)
public class ExampleRestClientTest {

    @Autowired
    private RemoteVehicleDetailsService service;

    @Autowired
    private MockRestServiceServer server;

    @Test
    public void getVehicleDetailsWhenResultIsSuccessShouldReturnDetails()
            throws Exception {
        this.server.expect(requestTo("/greet/details"))
                .andRespond(withSuccess("hello", MediaType.TEXT_PLAIN));
        String greeting = this.service.callRestService();
        assertThat(greeting).isEqualTo("hello");
    }

}

A list of the auto-configuration that is enabled by @RestClientTest can be found in the appendix.

41.3.12 Auto-configured Spring REST Docs tests

The @AutoConfigureRestDocs annotation can be used if you want to use Spring REST Docs in your tests. It will automatically configure MockMvc to use Spring REST Docs and remove the need for Spring REST Docs' JUnit rule.

import org.junit.Test;
import org.junit.runner.RunWith;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@RunWith(SpringRunner.class)
@WebMvcTest(UserController.class)
@AutoConfigureRestDocs("target/generated-snippets")
public class UserDocumentationTests {

    @Autowired
    private MockMvc mvc;

    @Test
    public void listUsers() throws Exception {
        this.mvc.perform(get("/users").accept(MediaType.TEXT_PLAIN))
                .andExpect(status().isOk())
                .andDo(document("list-users"));
    }

}

In addition to configuring the output directory, @AutoConfigureRestDocs can also configure the host, scheme, and port that will appear in any documented URIs. If you require more control over Spring REST Docs' configuration a RestDocsMockMvcConfigurationCustomizer bean can be used:

@TestConfiguration
static class CustomizationConfiguration
        implements RestDocsMockMvcConfigurationCustomizer {

    @Override
    public void customize(MockMvcRestDocumentationConfigurer configurer) {
        configurer.snippets().withTemplateFormat(TemplateFormats.markdown());
    }

}

If you want to make use of Spring REST Docs' support for a parameterized output directory, you can create a RestDocumentationResultHandler bean. The auto-configuration will call alwaysDo with this result handler, thereby causing each MockMvc call to automatically generate the default snippets:

@TestConfiguration
static class ResultHandlerConfiguration {

    @Bean
    public RestDocumentationResultHandler restDocumentation() {
        return MockMvcRestDocumentation.document("{method-name}");
    }

}

41.3.13 Using Spock to test Spring Boot applications

If you wish to use Spock to test a Spring Boot application you should add a dependency on Spock�s spock-spring module to your application�s build. spock-spring integrates Spring�s test framework into Spock. Exactly how you can use Spock to test a Spring Boot application depends on the version of Spock that you are using.

[Note] Note

Spring Boot provides dependency management for Spock 1.0. If you wish to use Spock 1.1 you should override the spock.version property in your build.gradle or pom.xml file.

When using Spock 1.1, the annotations described above can only be used and you can annotate your Specification with @SpringBootTest to suit the needs of your tests.

When using Spock 1.0, @SpringBootTest will not work for a web project. You need to use @SpringApplicationConfiguration and @WebIntegrationTest(randomPort = true). Being unable to use @SpringBootTest means that you also lose the auto-configured TestRestTemplate bean. You can create an equivalent bean yourself using the following configuration:

@Configuration
static class TestRestTemplateConfiguration {

    @Bean
    public TestRestTemplate testRestTemplate(
            ObjectProvider<RestTemplateBuilder> builderProvider,
            Environment environment) {
        RestTemplateBuilder builder = builderProvider.getIfAvailable();
        TestRestTemplate template = builder == null ? new TestRestTemplate()
                : new TestRestTemplate(builder.build());
        template.setUriTemplateHandler(new LocalHostUriTemplateHandler(environment));
        return template;
    }

}

41.4 Test utilities

A few test utility classes are packaged as part of spring-boot that are generally useful when testing your application.

41.4.1 ConfigFileApplicationContextInitializer

ConfigFileApplicationContextInitializer is an ApplicationContextInitializer that can apply to your tests to load Spring Boot application.properties files. You can use this when you don�t need the full features provided by @SpringBootTest.

@ContextConfiguration(classes = Config.class,
                    initializers = ConfigFileApplicationContextInitializer.class)
[Note] Note

Using ConfigFileApplicationContextInitializer alone won�t provide support for @Value("${�​}") injection. Its only job is to ensure that application.properties files are loaded into Spring�s Environment. For @Value support you need to either additionally configure a PropertySourcesPlaceholderConfigurer or use @SpringBootTest where one will be auto-configured for you.

41.4.2 EnvironmentTestUtils

EnvironmentTestUtils allows you to quickly add properties to a ConfigurableEnvironment or ConfigurableApplicationContext. Simply call it with key=value strings:

EnvironmentTestUtils.addEnvironment(env, "org=Spring", "name=Boot");

41.4.3 OutputCapture

OutputCapture is a JUnit Rule that you can use to capture System.out and System.err output. Simply declare the capture as a @Rule then use toString() for assertions:

import org.junit.Rule;
import org.junit.Test;
import org.springframework.boot.test.rule.OutputCapture;

import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;

public class MyTest {

	@Rule
	public OutputCapture capture = new OutputCapture();

	@Test
	public void testName() throws Exception {
		System.out.println("Hello World!");
		assertThat(capture.toString(), containsString("World"));
	}

}

41.4.4 TestRestTemplate

TestRestTemplate is a convenience alternative to Spring�s RestTemplate that is useful in integration tests. You can get a vanilla template or one that sends Basic HTTP authentication (with a username and password). In either case the template will behave in a test-friendly way by not throwing exceptions on server-side errors. It is recommended, but not mandatory, to use Apache HTTP Client (version 4.3.2 or better), and if you have that on your classpath the TestRestTemplate will respond by configuring the client appropriately. If you do use Apache�s HTTP client some additional test-friendly features will be enabled:

  • Redirects will not be followed (so you can assert the response location)
  • Cookies will be ignored (so the template is stateless)

TestRestTemplate can be instantiated directly in your integration tests:

public class MyTest {

                    private TestRestTemplate template
                    = new TestRestTemplate();

                    @Test
                    public void testRequest() throws                    Exception { HttpHeaders headers = template.getForEntity("http://myhost.com/example", String.class).getHeaders(); assertThat(headers.getLocation().toString(), containsString(
                    "myotherhost")); } }

                        

Alternatively, if you are using the @SpringBootTest annotation with WebEnvironment.RANDOM_PORT or WebEnvironment.DEFINED_PORT, you can just inject a fully configured TestRestTemplate and start using it. If necessary, additional customizations can be applied via the RestTemplateBuilder bean. Any URLs that do not specify a host and port will automatically connect to the embedded server:

@RunWith(SpringRunner.class)
@SpringBootTest
public class MyTest {

	@Autowired
	private TestRestTemplate template;

	@Test
	public void testRequest() throws Exception {
		HttpHeaders headers = template.getForEntity("/example", String.class).getHeaders();
		assertThat(headers.getLocation().toString(), containsString("myotherhost"));
	}

	@TestConfiguration
	static class Config {

		@Bean
		public RestTemplateBuilder restTemplateBuilder() {
			return new RestTemplateBuilder()
				.additionalMessageConverters(...)
				.customizers(...);
		}

	}

}

42. WebSockets

Spring Boot provides WebSockets auto-configuration for embedded Tomcat (8 and 7), Jetty 9 and Undertow. If you�re deploying a war file to a standalone container, Spring Boot assumes that the container will be responsible for the configuration of its WebSocket support.

Spring Framework provides rich WebSocket support that can be easily accessed via the spring-boot-starter-websocket module.

43. Web Services

Spring Boot provides Web Services auto-configuration so that all is required is defining your Endpoints.

The Spring Web Services features can be easily accessed via the spring-boot-starter-webservices module.

44. Creating your own auto-configuration

If you work in a company that develops shared libraries, or if you work on an open-source or commercial library, you might want to develop your own auto-configuration. Auto-configuration classes can be bundled in external jars and still be picked-up by Spring Boot.

Auto-configuration can be associated to a "starter" that provides the auto-configuration code as well as the typical libraries that you would use with it. We will first cover what you need to know to build your own auto-configuration and we will move on to the typical steps required to create a custom starter.

[Tip] Tip

A demo project is available to showcase how you can create a starter step by step.

44.1 Understanding auto-configured beans

Under the hood, auto-configuration is implemented with standard @Configuration classes. Additional @Conditional annotations are used to constrain when the auto-configuration should apply. Usually auto-configuration classes use @ConditionalOnClass and @ConditionalOnMissingBean annotations. This ensures that auto-configuration only applies when relevant classes are found and when you have not declared your own @Configuration.

You can browse the source code of spring-boot-autoconfigure to see the @Configuration classes that we provide (see the META-INF/spring.factories file).

44.2 Locating auto-configuration candidates

Spring Boot checks for the presence of a META-INF/spring.factories file within your published jar. The file should list your configuration classes under the EnableAutoConfiguration key.

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.mycorp.libx.autoconfigure.LibXAutoConfiguration,\
com.mycorp.libx.autoconfigure.LibXWebAutoConfiguration

You can use the @AutoConfigureAfter or @AutoConfigureBefore annotations if your configuration needs to be applied in a specific order. For example, if you provide web-specific configuration, your class may need to be applied after WebMvcAutoConfiguration.

If you want to order certain auto-configurations that shouldn�t have any direct knowledge of each other, you can also use @AutoconfigureOrder. That annotation has the same semantic as the regular @Order annotation but provides a dedicated order for auto-configuration classes.

[Note] Note

Auto-configurations have to be loaded that way only. Make sure that they are defined in a specific package space and that they are never the target of component scan in particular.

44.3 Condition annotations

You almost always want to include one or more @Conditional annotations on your auto-configuration class. The @ConditionalOnMissingBean is one common example that is used to allow developers to �override� auto-configuration if they are not happy with your defaults.

Spring Boot includes a number of @Conditional annotations that you can reuse in your own code by annotating @Configuration classes or individual @Bean methods.

44.3.1 Class conditions

The @ConditionalOnClass and @ConditionalOnMissingClass annotations allows configuration to be included based on the presence or absence of specific classes. Due to the fact that annotation metadata is parsed using ASM you can actually use the value attribute to refer to the real class, even though that class might not actually appear on the running application classpath. You can also use the name attribute if you prefer to specify the class name using a String value.

[Tip] Tip

If you are using @ConditionalOnClass or @ConditionalOnMissingClass as a part of a meta-annotation to compose your own composed annotations you must use name as referring to the class in such a case is not handled.

44.3.2 Bean conditions

The @ConditionalOnBean and @ConditionalOnMissingBean annotations allow a bean to be included based on the presence or absence of specific beans. You can use the value attribute to specify beans by type, or name to specify beans by name. The search attribute allows you to limit the ApplicationContext hierarchy that should be considered when searching for beans.

When placed on a @Bean method, the target type defaults to the return type of the method, for instance:

@Configuration
public class MyAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public MyService myService() { ... }

}

In the example above, the myService bean is going to be created if no bean of type MyService is already contained in the ApplicationContext.

[Tip] Tip

You need to be very careful about the order that bean definitions are added as these conditions are evaluated based on what has been processed so far. For this reason, we recommend only using @ConditionalOnBean and @ConditionalOnMissingBean annotations on auto-configuration classes (since these are guaranteed to load after any user-defined beans definitions have been added).

[Note] Note

@ConditionalOnBean and @ConditionalOnMissingBean do not prevent @Configuration classes from being created. Using these conditions at the class level is equivalent to marking each contained @Bean method with the annotation.

44.3.3 Property conditions

The @ConditionalOnProperty annotation allows configuration to be included based on a Spring Environment property. Use the prefix and name attributes to specify the property that should be checked. By default any property that exists and is not equal to false will be matched. You can also create more advanced checks using the havingValue and matchIfMissing attributes.

44.3.4 Resource conditions

The @ConditionalOnResource annotation allows configuration to be included only when a specific resource is present. Resources can be specified using the usual Spring conventions, for example, file:/home/user/test.dat.

44.3.5 Web application conditions

The @ConditionalOnWebApplication and @ConditionalOnNotWebApplication annotations allow configuration to be included depending on whether the application is a 'web application'. A web application is any application that is using a Spring WebApplicationContext, defines a session scope or has a StandardServletEnvironment.

44.3.6 SpEL expression conditions

The @ConditionalOnExpression annotation allows configuration to be included based on the result of a SpEL expression.

44.4 Creating your own starter

A full Spring Boot starter for a library may contain the following components:

  • The autoconfigure module that contains the auto-configuration code.
  • The starter module that provides a dependency to the autoconfigure module as well as the library and any additional dependencies that are typically useful. In a nutshell, adding the starter should be enough to start using that library.
[Tip] Tip

You may combine the auto-configuration code and the dependency management in a single module if you don�t need to separate those two concerns.

44.4.1 Naming

Please make sure to provide a proper namespace for your starter. Do not start your module names with spring-boot, even if you are using a different Maven groupId. We may offer an official support for the thing you�re auto-configuring in the future.

Here is a rule of thumb. Let�s assume that you are creating a starter for "acme", name the auto-configure module acme-spring-boot-autoconfigure and the starter acme-spring-boot-starter. If you only have one module combining the two, use acme-spring-boot-starter.

Besides, if your starter provides configuration keys, use a proper namespace for them. In particular, do not include your keys in the namespaces that Spring Boot uses (e.g. server, management, spring, etc). These are "ours" and we may improve/modify them in the future in such a way it could break your things.

Make sure to trigger meta-data generation so that IDE assistance is available for your keys as well. You may want to review the generated meta-data (META-INF/spring-configuration-metadata.json) to make sure your keys are properly documented.

44.4.2 Autoconfigure module

The autoconfigure module contains everything that is necessary to get started with the library. It may also contain configuration keys definition (@ConfigurationProperties) and any callback interface that can be used to further customize how the components are initialized.

[Tip] Tip

You should mark the dependencies to the library as optional so that you can include the autoconfigure module in your projects more easily. If you do it that way, the library won�t be provided and Spring Boot will back off by default.

44.4.3 Starter module

The starter is an empty jar, really. Its only purpose is to provide the necessary dependencies to work with the library; see it as an opinionated view of what is required to get started.

Do not make assumptions about the project in which your starter is added. If the library you are auto-configuring typically requires other starters, mention them as well. Providing a proper set of default dependencies may be hard if the number of optional dependencies is high as you should avoid bringing unnecessary dependencies for a typical usage of the library.

45. What to read next

If you want to learn more about any of the classes discussed in this section you can check out the Spring Boot API documentation or you can browse the source code directly. If you have specific questions, take a look at the how-to section.

If you are comfortable with Spring Boot�s core features, you can carry on and read about production-ready features.

Part V. Spring Boot Actuator: Production-ready features

Spring Boot includes a number of additional features to help you monitor and manage your application when it�s pushed to production. You can choose to manage and monitor your application using HTTP endpoints, with JMX or even by remote shell (SSH or Telnet). Auditing, health and metrics gathering can be automatically applied to your application.

Actuator HTTP endpoints are only available with a Spring MVC-based application. In particular, it will not work with Jersey unless you enable Spring MVC as well.

46. Enabling production-ready features

The spring-boot-actuator module provides all of Spring Boot�s production-ready features. The simplest way to enable the features is to add a dependency to the spring-boot-starter-actuator �Starter�.

To add the actuator to a Maven based project, add the following �Starter� dependency:

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

For Gradle, use the declaration:

dependencies {
    compile("org.springframework.boot:spring-boot-starter-actuator")
}

47. Endpoints

Actuator endpoints allow you to monitor and interact with your application. Spring Boot includes a number of built-in endpoints and you can also add your own. For example the health endpoint provides basic application health information.

The way that endpoints are exposed will depend on the type of technology that you choose. Most applications choose HTTP monitoring, where the ID of the endpoint is mapped to a URL. For example, by default, the health endpoint will be mapped to /health.

The following technology agnostic endpoints are available:

ID Description Sensitive Default

actuator

Provides a hypermedia-based �discovery page� for the other endpoints. Requires Spring HATEOAS to be on the classpath.

true

auditevents

Exposes audit events information for the current application.

true

autoconfig

Displays an auto-configuration report showing all auto-configuration candidates and the reason why they �were� or �were not� applied.

true

beans

Displays a complete list of all the Spring beans in your application.

true

configprops

Displays a collated list of all @ConfigurationProperties.

true

dump

Performs a thread dump.

true

env

Exposes properties from Spring�s ConfigurableEnvironment.

true

flyway

Shows any Flyway database migrations that have been applied.

true

health

Shows application health information (when the application is secure, a simple �status� when accessed over an unauthenticated connection or full message details when authenticated).

false

info

Displays arbitrary application info.

false

loggers

Shows and modifies the configuration of loggers in the application.

true

liquibase

Shows any Liquibase database migrations that have been applied.

true

metrics

Shows �metrics� information for the current application.

true

mappings

Displays a collated list of all @RequestMapping paths.

true

shutdown

Allows the application to be gracefully shutdown (not enabled by default).

true

trace

Displays trace information (by default the last 100 HTTP requests).

true

If you are using Spring MVC, the following additional endpoints can also be used:

ID Description Sensitive Default

docs

Displays documentation, including example requests and responses, for the Actuator�s endpoints. Requires spring-boot-actuator-docs to be on the classpath.

false

heapdump

Returns a GZip compressed hprof heap dump file.

true

jolokia

Exposes JMX beans over HTTP (when Jolokia is on the classpath).

true

logfile

Returns the contents of the logfile (if logging.file or logging.path properties have been set). Supports the use of the HTTP Range header to retrieve part of the log file�s content.

true

[Note] Note

Depending on how an endpoint is exposed, the sensitive property may be used as a security hint. For example, sensitive endpoints will require a username/password when they are accessed over HTTP (or simply disabled if web security is not enabled).

47.1 Customizing endpoints

Endpoints can be customized using Spring properties. You can change if an endpoint is enabled, if it is considered sensitive and even its id.

For example, here is an application.properties that changes the sensitivity and id of the beans endpoint and also enables shutdown.

endpoints.beans.id=springbeans
                        endpoints.beans.sensitive=false
                        endpoints.shutdown.enabled=true
[Note] Note

The prefix ‟endpoints + . + name� is used to uniquely identify the endpoint that is being configured.

By default, all endpoints except for shutdown are enabled. If you prefer to specifically �opt-in� endpoint enablement you can use the endpoints.enabled property. For example, the following will disable all endpoints except for info:

endpoints.enabled=false
endpoints.info.enabled=true

Likewise, you can also choose to globally set the �sensitive� flag of all endpoints. By default, the sensitive flag depends on the type of endpoint (see the table above). For example, to mark all endpoints as sensitive except info:

endpoints.sensitive=true
endpoints.info.sensitive=false

47.2 Hypermedia for actuator MVC endpoints

If endpoints.hypermedia.enabled is set to true and Spring HATEOAS is on the classpath (e.g. through the spring-boot-starter-hateoas or if you are using Spring Data REST) then the HTTP endpoints from the Actuator are enhanced with hypermedia links, and a �discovery page� is added with links to all the endpoints. The �discovery page� is available on /actuator by default. It is implemented as an endpoint, allowing properties to be used to configure its path ( endpoints.actuator.path) and whether or not it is enabled ( endpoints.actuator.enabled).

When a custom management context path is configured, the �discovery page� will automatically move from /actuator to the root of the management context. For example, if the management context path is /management then the discovery page will be available from /management.

If the HAL Browser is on the classpath via its webjar (org.webjars:hal-browser), or via the spring-data-rest-hal-browser then an HTML �discovery page�, in the form of the HAL Browser, is also provided.

47.3 CORS support

Cross-origin resource sharing (CORS) is a W3C specification that allows you to specify in a flexible way what kind of cross domain requests are authorized. Actuator�s MVC endpoints can be configured to support such scenarios.

CORS support is disabled by default and is only enabled once the endpoints.cors.allowed-origins property has been set. The configuration below permits GET and POST calls from the example.com domain:

endpoints.cors.allowed-origins=http://example.com
endpoints.cors.allowed-methods=GET,POST
[Tip] Tip

Check EndpointCorsProperties for a complete list of options.

47.4 Adding custom endpoints

If you add a @Bean of type Endpoint then it will automatically be exposed over JMX and HTTP (if there is an server available). An HTTP endpoints can be customized further by creating a bean of type MvcEndpoint. Your MvcEndpoint is not a @Controller but it can use @RequestMapping (and @Managed*) to expose resources.

[Tip] Tip

If you are doing this as a library feature consider adding a configuration class annotated with @ManagementContextConfiguration to /META-INF/spring.factories under the key org.springframework.boot.actuate.autoconfigure.ManagementContextConfiguration. If you do that then the endpoint will move to a child context with all the other MVC endpoints if your users ask for a separate management port or address. A configuration declared this way can be a WebConfigurerAdapter if it wants to add static resources (for instance) to the management endpoints.

47.5 Health information

Health information can be used to check the status of your running application. It is often used by monitoring software to alert someone if a production system goes down. The default information exposed by the health endpoint depends on how it is accessed. For an unauthenticated connection in a secure application a simple �status� message is returned, and for an authenticated connection additional details are also displayed (see Section 48.7, �HTTP health endpoint format and access restrictions� for HTTP details).

Health information is collected from all HealthIndicator beans defined in your ApplicationContext. Spring Boot includes a number of auto-configured HealthIndicators and you can also write your own.

47.6 Security with HealthIndicators

Information returned by HealthIndicators is often somewhat sensitive in nature. For example, you probably don�t want to publish details of your database server to the world. For this reason, by default, only the health status is exposed over an unauthenticated HTTP connection. If you are happy for complete health information to always be exposed you can set endpoints.health.sensitive to false.

Health responses are also cached to prevent �denial of service� attacks. Use the endpoints.health.time-to-live property if you want to change the default cache period of 1000 milliseconds.

47.6.1 Auto-configured HealthIndicators

The following HealthIndicators are auto-configured by Spring Boot when appropriate: