Spring Boot 标准 IO 功能
大多数应用程序在某些时候需要处理输入和输出问题。Spring Boot 提供实用程序和与一系列技术的集成,以在您需要 IO 功能时提供帮助。本节涵盖标准 IO 功能(例如缓存和验证)以及更高级的主题(例如调度和分布式事务)。我们还将介绍调用远程 REST 或 SOAP 服务以及发送电子邮件。
1.缓存
Spring 框架支持透明地向应用程序添加缓存。在其核心,抽象将缓存应用于方法,从而减少基于缓存中可用信息的执行次数。缓存逻辑是透明应用的,对调用者没有任何干扰。只要使用@EnableCaching
注解启用缓存支持,Spring Boot 就会自动配置缓存基础结构。
简而言之,要向服务的操作添加缓存,请将相关注释添加到其方法中,如以下示例所示:
此示例演示了在可能代价高昂的操作中使用缓存。在调用 之前computePiDecimal
,抽象会在piDecimals
缓存中查找与i
参数匹配的条目。如果找到条目,缓存中的内容会立即返回给调用者,并且不会调用该方法。否则,调用该方法,并在返回值之前更新缓存。
如果不添加任何特定的缓存库,Spring Boot 会自动配置一个简单的提供程序,该提供程序在内存中使用并发映射。当需要缓存时(例如piDecimals
在前面的示例中),此提供程序会为您创建它。不建议将简单提供程序用于生产用途,但它非常适合入门并确保您了解这些功能。当您决定使用缓存提供程序时,请务必阅读其文档以了解如何配置应用程序使用的缓存。几乎所有提供程序都要求您显式配置您在应用程序中使用的每个缓存。有些提供了一种自定义属性定义的默认缓存的方法spring.cache.cache-names
。
1.1支持的缓存提供程序
缓存抽象不提供实际的存储,它依赖于org.springframework.cache.Cache
和org.springframework.cache.CacheManager
接口实现的抽象。
如果您尚未定义类型CacheManager
或CacheResolver
命名的 bean cacheResolver
(请参阅 参考资料CachingConfigurer),Spring Boot 会尝试检测以下提供者(按指示的顺序):
- 通用的
- JCache (JSR-107)(EhCache 3、Hazelcast、Infinispan 等)
- EhCache 2.x
- 榛树
- 英菲尼斯潘
- 沙发底座
- 雷迪斯
- 咖啡因
- Cache2k
- 简单的
此外, Apache Geode 的Spring Boot提供了使用 Apache Geode 作为缓存提供程序的自动配置。
如果CacheManager
是由 Spring Boot 自动配置的,您可以在完全初始化之前通过公开实现该CacheManagerCustomizer
接口的 bean 进一步调整其配置。以下示例设置一个标志,表示null
不应将值传递给底层映射:
1.1.1。通用的
如果上下文定义了至少一个org.springframework.cache.Cache
bean ,则使用通用缓存。创建了一个CacheManager
包装该类型的所有 bean。
1.1.2JCache (JSR-107)
JCache通过类路径上的 a 来引导javax.cache.spi.CachingProvider
(即,类路径上存在一个符合 JSR-107 的缓存库),并且JCacheCacheManager
由spring-boot-starter-cache
“Starter”提供。有各种兼容的库可用,Spring Boot 为 Ehcache 3、Hazelcast 和 Infinispan 提供了依赖管理。也可以添加任何其他兼容的库。
可能存在多个提供者,在这种情况下必须明确指定提供者。即使 JSR-107 标准没有强制使用标准化的方式来定义配置文件的位置,Spring Boot 也会尽最大努力适应使用实现细节设置缓存,如下例所示:
特性
有两种方法可以自定义底层javax.cache.cacheManager
:
- 可以通过设置
spring.cache.cache-names
属性在启动时创建缓存。如果定义了自定义javax.cache.configuration.Configuration
bean,则使用它来自定义它们。 -
org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer
bean 是通过引用来调用的,以CacheManager
实现完全定制。
1.1.3EhCache 2.x
ehcache.xml
如果可以在类路径的根目录找到名为的文件,则使用EhCache 2.x。如果找到 EhCache 2.x, “Starter”EhCacheCacheManager
提供的spring-boot-starter-cache
用于引导缓存管理器。也可以提供备用配置文件,如以下示例所示:
特性
1.1.4榛树
Spring Boot对 Hazelcast 具有一般支持。如果 aHazelcastInstance
已被自动配置,它会自动包装在 a 中CacheManager
。
1.1.5英菲尼斯潘
Infinisan没有默认配置文件位置,因此必须明确指定。否则,将使用默认引导程序。
特性
可以通过设置spring.cache.cache-names
属性在启动时创建缓存。如果定义了自定义ConfigurationBuilder
bean,它将用于自定义缓存。
1.1.6沙发底座
如果 Spring Data Couchbase 可用并且 Couchbase 已配置,则 aCouchbaseCacheManager
是自动配置的。可以通过设置spring.cache.cache-names
属性在启动时创建额外的缓存,并且可以使用spring.cache.couchbase.*
属性配置缓存默认值。例如,以下配置创建cache1
并cache2
缓存条目过期时间为 10 分钟:
特性
如果您需要对配置进行更多控制,请考虑注册一个CouchbaseCacheManagerBuilderCustomizer
bean。cache1
以下示例显示了一个为和配置特定条目过期的定制器cache2
:
1.1.7雷迪斯
如果Redis可用且已配置,则 aRedisCacheManager
是自动配置的。可以通过设置spring.cache.cache-names
属性在启动时创建额外的缓存,并且可以使用spring.cache.redis.*
属性配置缓存默认值。例如,以下配置以10 分钟的生存时间cache1
创建和cache2
缓存:
特性
如果您需要对配置进行更多控制,请考虑注册一个RedisCacheManagerBuilderCustomizer
bean。cache1
以下示例显示了一个自定义程序,该自定义程序为和配置特定的生存时间cache2
:
1.1.8咖啡因
Caffeine是 Java 8 对 Guava 缓存的重写,它取代了对 Guava 的支持。如果存在咖啡因,则会自动配置一个CaffeineCacheManager
(由“Starter”提供)。spring-boot-starter-cache
可以通过设置属性在启动时创建缓存,spring.cache.cache-names
并且可以通过以下之一自定义缓存(按指示的顺序):
- 由定义的缓存规范
spring.cache.caffeine.spec
- 定义了一个
com.github.benmanes.caffeine.cache.CaffeineSpec
bean - 定义了一个
com.github.benmanes.caffeine.cache.Caffeine
bean
例如,以下配置创建cache1
和cache2
缓存最大大小为 500,生存时间为 10 分钟
特性
如果com.github.benmanes.caffeine.cache.CacheLoader
定义了 bean,它会自动关联到CaffeineCacheManager
. 由于CacheLoader
将与缓存管理器管理的所有CacheLoader
缓存相关联,因此必须将其定义为。自动配置忽略任何其他泛型类型。
1.1.9Cache2k
Cache2k是一个内存缓存。如果存在 Cache2k spring 集成,则 aSpringCache2kCacheManager
是自动配置的。
可以通过设置spring.cache.cache-names
属性在启动时创建缓存。可以使用Cache2kBuilderCustomizer
bean 自定义缓存默认值。以下示例显示了一个自定义程序,它将缓存容量配置为 200 个条目,有效期为 5 分钟:
1.1.10。简单的
如果找不到其他提供程序,ConcurrentHashMap
则配置使用 a 作为缓存存储的简单实现。如果您的应用程序中不存在缓存库,则这是默认设置。默认情况下,缓存是根据需要创建的,但您可以通过设置cache-names
属性来限制可用缓存的列表。例如,如果您只需要cache1
和cache2
缓存,请cache-names
按如下方式设置属性:
特性
如果您这样做并且您的应用程序使用未列出的缓存,那么它在运行时需要缓存时会失败,但在启动时不会失败。如果您使用未声明的缓存,这类似于“真实”缓存提供程序的行为方式。
1.1.11没有任何
当@EnableCaching
您的配置中存在时,也需要合适的缓存配置。如果您需要在某些环境中完全禁用缓存,请强制缓存类型none
使用无操作实现,如下例所示:
特性
2. 榛树
如果Hazelcast在类路径上并且找到了合适的配置,Spring Boot 会自动配置一个HazelcastInstance
您可以在应用程序中注入的配置。
Spring Boot 首先尝试通过检查以下配置选项来创建客户端:
- 一个
com.hazelcast.client.config.ClientConfig
豆子的存在。 - 由
spring.hazelcast.config
属性定义的配置文件。 -
hazelcast.client.config
系统属性的存在。 - A
hazelcast-client.xml
在工作目录或类路径的根目录中。 - A
hazelcast-client.yaml
(或hazelcast-client.yml
)在工作目录或类路径的根目录中。
如果无法创建客户端,Spring Boot 会尝试配置嵌入式服务器。如果你定义了一个com.hazelcast.config.Config
bean,Spring Boot 就会使用它。如果您的配置定义了实例名称,Spring Boot 会尝试定位现有实例而不是创建新实例。
您还可以通过配置指定要使用的 Hazelcast 配置文件,如下例所示:
特性
否则,Spring Boot 会尝试从默认位置查找 Hazelcast 配置:hazelcast.xml
在工作目录或类路径的根目录中,或在相同位置的.yaml
/对应项。.yml
我们还检查是否hazelcast.config
设置了系统属性。有关更多详细信息,请参阅Hazelcast 文档。
3.石英调度器
Spring Boot 为使用Quartz 调度程序提供了多种便利,包括spring-boot-starter-quartz
“Starter”。如果 Quartz 可用,则 aScheduler
是自动配置的(通过SchedulerFactoryBean
抽象)。
以下类型的 Bean 会被自动拾取并与 相关联Scheduler
:
-
JobDetail
: 定义一个特定的 Job。JobDetail
可以使用JobBuilder
API 构建实例。 -
Calendar
. -
Trigger
:定义何时触发特定作业。
默认情况下,使用内存JobStore
。但是,如果DataSource
bean 在您的应用程序中可用并且相应地配置了spring.quartz.job-store-type
属性,则可以配置基于 JDBC 的存储,如以下示例所示:
特性
使用 JDBC 存储时,可以在启动时初始化模式,如下例所示:
特性
要让 Quartz 使用DataSource
除应用程序的 main 以外的bean,请DataSource
声明一个DataSource
bean,并用 .注释其@Bean
方法@QuartzDataSource
。这样做可以确保 Quartz-specificDataSource
被SchedulerFactoryBean
和 用于模式初始化。类似地,要让 Quartz 使用TransactionManager
非应用程序的 mainTransactionManager
声明一个TransactionManager
bean,@Bean
用 . 注释它的方法@QuartzTransactionManager
。
默认情况下,配置创建的作业不会覆盖已从持久作业存储中读取的已注册作业。要启用覆盖现有作业定义,请设置该spring.quartz.overwrite-existing-jobs
属性。
Quartz Scheduler 配置可以使用spring.quartz
属性和SchedulerFactoryBeanCustomizer
bean 进行自定义,这允许编程SchedulerFactoryBean
自定义。高级 Quartz 配置属性可以使用spring.quartz.properties.*
.
作业可以定义 setter 来注入数据映射属性。常规 bean 也可以通过类似的方式注入,如下例所示:
4. 发送电子邮件
Spring Framework 提供了使用接口发送电子邮件的抽象JavaMailSender
,Spring Boot 为其提供了自动配置以及启动模块。
如果spring.mail.host
相关库(由 定义spring-boot-starter-mail
)可用,JavaMailSender
则创建默认值(如果不存在)。可以通过命名空间中的配置项进一步自定义发送者spring.mail
。有关MailProperties更多详细信息,请参阅。
特别是,某些默认超时值是无限的,您可能需要更改它以避免线程被无响应的邮件服务器阻塞,如以下示例所示:
特性
也可以JavaMailSender
使用现有Session
的 JNDI 配置 a:
特性
设置a 时jndi-name
,它优先于所有其他与会话相关的设置。
5. 验证
只要类路径上有 JSR-303 实现(例如 Hibernate 验证器),Bean Validation 1.1 支持的方法验证功能就会自动启用。javax.validation
这让 bean 方法可以在其参数和/或返回值上使用约束进行注释。具有此类注释方法的目标类需要@Validated
在类型级别使用注释进行注释,以便在其方法中搜索内联约束注释。
例如,以下服务触发第一个参数的验证,确保其大小在 8 到 10 之间:
在约束消息中MessageSource
解析时使用应用程序的。{parameters}
这允许您将应用程序的messages.properties文件用于 Bean 验证消息。解析参数后,使用 Bean Validation 的默认插值器完成消息插值。
6.调用REST服务
如果您的应用程序调用远程 REST 服务,Spring Boot 使用 aRestTemplate
或WebClient
.
6.1休息模板
如果需要从应用程序调用远程 REST 服务,可以使用 Spring Framework 的RestTemplate类。由于RestTemplate
实例通常需要在使用之前进行自定义,因此 Spring Boot 不提供任何单个自动配置的RestTemplate
bean。但是,它确实会自动配置 a RestTemplateBuilder
,可用于RestTemplate
在需要时创建实例。自动配置RestTemplateBuilder
可确保将 sensibleHttpMessageConverters
应用于RestTemplate
实例。
下面的代码展示了一个典型的例子:
6.1.1. RestTemplate 自定义
有三种主要的RestTemplate
自定义方法,具体取决于您希望自定义应用的范围。
要使任何自定义的范围尽可能窄,请注入自动配置RestTemplateBuilder
,然后根据需要调用其方法。每个方法调用都会返回一个新RestTemplateBuilder
实例,因此自定义只会影响构建器的这种使用。
要进行应用程序范围的附加定制,请使用RestTemplateCustomizer
bean。所有这些 bean 都会自动注册到 auto-configuredRestTemplateBuilder
中,并应用于使用它构建的任何模板。
以下示例显示了一个自定义程序,它为所有主机配置了代理的使用,除了192.168.0.5
:
最后,您可以定义自己的RestTemplateBuilder
bean。这样做将替换自动配置的构建器。如果您希望RestTemplateCustomizer
将任何 bean 应用于您的自定义构建器,就像自动配置所做的那样,请使用RestTemplateBuilderConfigurer
. 以下示例公开了RestTemplateBuilder
与 Spring Boot 的自动配置所做的匹配,除了还指定了自定义连接和读取超时:
爪哇
科特林
RestTemplateBuilder
最极端(并且很少使用)的选项是在不使用配置器的情况下创建自己的bean。除了替换自动配置的构建器之外,这还可以防止RestTemplateCustomizer
使用任何 bean。
6.2. 网络客户端
如果你的类路径上有 Spring WebFlux,你也可以选择使用WebClient
来调用远程 REST 服务。与 相比RestTemplate
,这个客户端有更多的功能感觉并且是完全反应式的。您可以在 Spring Framework 文档WebClient
的专用部分中了解更多信息。
Spring Boot 为您创建并预配置了一个WebClient.Builder
。强烈建议将其注入您的组件并使用它来创建WebClient
实例。Spring Boot 正在配置该构建器以共享 HTTP 资源,以与服务器相同的方式反映编解码器设置(请参阅WebFlux HTTP 编解码器自动配置)等等。
下面的代码展示了一个典型的例子:
6.2.1. WebClient 运行时
Spring Boot 将根据应用程序类路径上可用的库自动检测ClientHttpConnector
使用哪个来驱动。WebClient
目前支持 Reactor Netty、Jetty RS 客户端和 Apache HttpClient。
启动器默认spring-boot-starter-webflux
依赖io.projectreactor.netty:reactor-netty
,它带来了服务器和客户端的实现。如果您选择使用 Jetty 作为响应式服务器,您应该添加对 Jetty Reactive HTTP 客户端库的依赖,org.eclipse.jetty:jetty-reactive-httpclient
. 对服务器和客户端使用相同的技术有其优势,因为它会自动在客户端和服务器之间共享 HTTP 资源。
开发人员可以通过提供自定义ReactorResourceFactory
或JettyResourceFactory
bean 来覆盖 Jetty 和 Reactor Netty 的资源配置——这将应用于客户端和服务器。
如果您希望为客户端覆盖该选择,您可以定义自己的ClientHttpConnector
bean 并完全控制客户端配置。
WebClient您可以在 Spring Framework 参考文档中了解有关配置选项的更多信息。
6.2.2. Web客户端定制
有三种主要的WebClient
自定义方法,具体取决于您希望自定义应用的范围。
要使任何自定义的范围尽可能窄,请注入自动配置WebClient.Builder
,然后根据需要调用其方法。 WebClient.Builder
实例是有状态的:构建器上的任何更改都会反映在随后使用它创建的所有客户端中。如果您想使用同一个构建器创建多个客户端,您还可以考虑使用WebClient.Builder other = builder.clone();
.
要对所有WebClient.Builder
实例进行应用程序范围的附加定制,您可以声明WebClientCustomizer
bean 并WebClient.Builder
在注入点进行本地更改。
最后,您可以回退到原始 API 并使用WebClient.create()
. 在这种情况下,不会应用自动配置或WebClientCustomizer
。
7. 网络服务
Spring Boot 提供 Web 服务自动配置,因此您所要做的就是定义您的Endpoints
.
使用该模块可以轻松访问Spring Web Services 功能。spring-boot-starter-webservices
SimpleWsdl11Definition
SimpleXsdSchema
可以分别为您的 WSDL 和 XSD 自动创建和bean。为此,请配置它们的位置,如以下示例所示:
特性
7.1使用 WebServiceTemplate 调用 Web 服务
如果需要从应用程序调用远程 Web 服务,可以使用WebServiceTemplate该类。由于WebServiceTemplate
实例通常需要在使用之前进行自定义,因此 Spring Boot 不提供任何单个自动配置的WebServiceTemplate
bean。但是,它确实会自动配置 a WebServiceTemplateBuilder
,可用于WebServiceTemplate
在需要时创建实例。
下面的代码展示了一个典型的例子:
默认情况下,使用类路径上可用的 HTTP 客户端库WebServiceTemplateBuilder
检测合适的基于HTTP 的。WebServiceMessageSender
您还可以自定义读取和连接超时,如下所示:
8. 使用 JTA 的分布式事务
Spring Boot 使用Atomikos嵌入式事务管理器支持跨多个 XA 资源的分布式 JTA 事务。部署到合适的 Java EE 应用服务器时也支持 JTA 事务。
当检测到 JTA 环境时,使用 SpringJtaTransactionManager
来管理事务。自动配置的 JMS、DataSource 和 JPA bean 已升级为支持 XA 事务。您可以使用标准的 Spring 习惯用法,例如@Transactional
,来参与分布式事务。如果您在 JTA 环境中并且仍想使用本地事务,则可以将spring.jta.enabled
属性设置false
为禁用 JTA 自动配置。
8.1使用 Atomikos 事务管理器
Atomikos是一种流行的开源事务管理器,可以嵌入到您的 Spring Boot 应用程序中。您可以使用spring-boot-starter-jta-atomikos
启动器来拉入适当的 Atomikos 库。Spring Boot 自动配置 Atomikos 并确保将适当depends-on
的设置应用于您的 Spring bean 以实现正确的启动和关闭顺序。
默认情况下,Atomikos 事务日志被写入transaction-logs
应用程序主目录(应用程序 jar 文件所在的目录)中的一个目录。您可以通过在文件中设置spring.jta.log-dir
属性来自定义此目录的位置。application.properties
以 开头的属性spring.jta.atomikos.properties
也可用于自定义 Atomikos UserTransactionServiceImp
。有关完整的详细信息,请参阅AtomikosPropertiesJavadoc。
8.2. 使用 Java EE 托管事务管理器
如果将 Spring Boot 应用程序打包为war
orear
文件并将其部署到 Java EE 应用程序服务器,则可以使用应用程序服务器的内置事务管理器。Spring Boot 尝试通过查看常见的 JNDI 位置(java:comp/UserTransaction
、java:comp/TransactionManager
等)来自动配置事务管理器。如果您使用应用服务器提供的事务服务,您通常还希望确保所有资源都由服务器管理并通过 JNDI 公开。Spring Boot 尝试通过ConnectionFactory
在 JNDI 路径(java:/JmsXA
或java:/XAConnectionFactory
)处查找 a 来自动配置 JMS,您可以使用该spring.datasource.jndi-name属性来配置您的DataSource
.
8.3. 混合 XA 和非 XA JMS 连接
使用 JTA 时,主 JMS ConnectionFactory
bean 是 XA 感知的并参与分布式事务。您可以注入您的 bean 而无需使用任何@Qualifier
:
在某些情况下,您可能希望使用非 XA 来处理某些 JMS 消息ConnectionFactory
。例如,您的 JMS 处理逻辑可能需要比 XA 超时更长的时间。
如果你想使用非 XA ConnectionFactory
,你可以使用nonXaJmsConnectionFactory
bean:
为了保持一致性,jmsConnectionFactory
bean 也使用 bean 别名来提供xaJmsConnectionFactory
:
8.4. 支持替代嵌入式事务管理器
和接口可用于支持替代的嵌入式事务管理器XAConnectionFactoryWrapper。XADataSourceWrapper接口负责包装beanXAConnectionFactory
并将XADataSource
它们作为常规 bean 公开ConnectionFactory
,DataSource
它们透明地注册到分布式事务中。DataSource 和 JMS 自动配置使用 JTA 变体,前提是您JtaTransactionManager
在ApplicationContext
.
AtomikosXAConnectionFactoryWrapper和AtomikosXADataSourceWrapper提供了如何编写 XA 包装器的很好的示例。
9.接下来要读什么
您现在应该对 Spring Boot 的核心特性以及 Spring Boot 通过自动配置提供支持的各种技术有了很好的理解。
接下来的几节将详细介绍如何将应用程序部署到云平台。您可以在下一节中阅读有关构建容器映像的内容或跳到生产就绪功能部分。