大多数应用程序都需要在某一时刻处理输入和输出问题。Spring Boot提供实用程序和与一系列技术的集成,以便在您需要IO功能时提供帮助。本节介绍缓存和验证等标准IO功能,以及调度和分布式事务等更高级的主题。我们还将介绍调用远程REST或SOAP服务以及发送电子邮件。
1. Caching
Spring框架支持透明地向应用程序添加缓存。在其核心,抽象将缓存应用于方法,从而根据缓存中的可用信息减少执行次数。缓存逻辑以透明方式应用,不会对调用者造成任何干扰。只要使用@EnableCering
注释启用了缓存支持,Spring Boot就会自动配置缓存基础设施。
Check the relevant section of the Spring Framework reference for more details. |
简而言之,要将缓存添加到服务的操作中,请将相关注释添加到其方法中,如下例所示:
@Component public class MyMathService { @Cacheable("piDecimals") public int computePiDecimal(int precision) { ... } }
此示例演示了如何在可能代价高昂的操作上使用缓存。在调用cultePiDecimal
之前,抽象在piDecimals
缓存中查找与i
参数匹配的条目。如果找到条目,缓存中的内容将立即返回给调用方,并且不会调用该方法。否则,将调用该方法,并在返回值之前更新缓存。
You can also use the standard JSR-107 (JCache) annotations (such as @CacheResult ) transparently. However, we strongly advise you to not mix and match the Spring Cache and JCache annotations. |
如果您没有添加任何特定的缓存库,则Spring Boot会自动配置一个使用内存中并发映射的简单提供程序。当需要缓存时(如前面示例中的piDecimals
),此提供程序会为您创建缓存。Simple提供程序并不是真正推荐用于生产用途,但对于入门和确保您理解这些功能来说,它是非常好的。当您决定使用缓存提供程序时,请务必阅读其文档,以了解如何配置您的应用程序使用的缓存。几乎所有提供程序都要求您显式配置在应用程序中使用的每个缓存。其中一些提供了一种方法来定制由spring.cache.cache-name
属性定义的默认缓存。
1.1. Supported Cache Providers
缓存抽象并不提供实际的存储,而是依赖于由org.springFrawork.cache.Cache
和org.springframework.cache.CacheManager
接口实现的抽象。
如果您尚未定义CacheManager
类型的Bean或名为cacheResolver
的CacheResolver
(请参阅CachingConfigurer
),Spring Boot将尝试检测以下提供程序(按指定顺序):
It is also possible to force a particular cache provider by setting the spring.cache.type property. Use this property if you need to disable caching altogether in certain environments (such as tests). |
Use the spring-boot-starter-cache “Starter” to quickly add basic caching dependencies. The starter brings in spring-context-support . If you add dependencies manually, you must include spring-context-support in order to use the JCache or Caffeine support. |
如果CacheManager
是由Spring Boot自动配置的,那么在它完全初始化之前,您可以通过公开实现CacheManagerCustomizer
接口的Bean来进一步调优其配置。下面的示例设置一个标志,表示空
值不应向下传递到基础映射:
@Configuration(proxyBeanMethods = false) public class MyCacheManagerConfiguration { @Bean public CacheManagerCustomizer<ConcurrentMapCacheManager> cacheManagerCustomizer() { return (cacheManager) -> cacheManager.setAllowNullValues(false); } }
In the preceding example, 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 is not invoked at all. You can have as many customizers as you want, and you can also order them by using @Order or Ordered . |
1.1.2. JCache (JSR-107)
JCache是通过类路径上存在的javax.cache.Spi.CachingProvider
(即类路径上存在一个符合JSR-107标准的缓存库)引导的,而JCacheCacheManager
是由Spring-boot-starter-cache
“starter”提供的。有各种兼容的库可用,而Spring Boot为Ehcache3、Hazelcast和Infinisspan提供了依赖项管理。也可以添加任何其他兼容的库。
可能会出现多个提供程序,在这种情况下,必须显式指定提供程序。即使JSR-107标准没有强制使用标准化的方式来定义配置文件的位置,Spring Boot也会尽最大努力使用实现细节来设置缓存,如下面的示例所示:
# Only necessary if more than one provider is present
spring.cache.jcache.provider=com.example.MyCachingProvider
spring.cache.jcache.config=classpath:example.xml
When a cache library offers both a native implementation and JSR-107 support, Spring Boot prefers the JSR-107 support, so that the same features are available if you switch to a different JSR-107 implementation. |
Spring Boot has 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. |
有两种方法可以定制底层的javax.cache.cacheManager
:
-
通过设置
spring.cache.cache-name
属性,可以在启动时创建缓存。如果定义了定制的javax.cache.configuration.Configuration
Bean,则使用它来自定义它们。 -
CacheManager Bean通过<
org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer
>CacheManager的引用进行调用,以实现完全定制。
If a standard javax.cache.CacheManager bean is defined, it is wrapped automatically in an org.springframework.cache.CacheManager implementation that the abstraction expects. No further customization is applied to it. |
1.1.3. Hazelcast
Spring Boot对Hazelcast有一般支持。如果已经自动配置了HazelCastInstance
,并且com.hazelcast:Hazelcast-Spring
在类路径上,那么它会自动包装在CacheManager
中。
Hazelcast can be used as a JCache compliant cache or as a Spring CacheManager compliant cache. When setting spring.cache.type to hazelcast , Spring Boot will use the CacheManager based implementation. If you want to use Hazelcast as a JCache compliant cache, set spring.cache.type to jcache . If you have multiple JCache compliant cache providers and want to force the use of Hazelcast, you have to explicitly set the JCache provider. |
1.1.4. Infinispan
Infinispan没有默认配置文件位置,因此必须显式指定。否则,将使用默认引导。
spring.cache.infinispan.config=infinispan.xml
通过设置spring.cache.cache-name
属性,可以在启动时创建缓存。如果定义了自定义ConfigurationBuilder
Bean,则使用它来自定义缓存。
为了与Spring Boot的Jakarta EE 9基线兼容,必须使用Infinisspan的-jakarta
模块。对于具有-jakarta
变量的每个模块,必须使用该变量来代替标准模块。例如,必须分别使用infinisspan-core-jakarta
和infinispanCommons-jakarta
来代替infinisspan-core
和infinisspan-Commons
。
1.1.5. Couchbase
如果Spring data Couchbase可用,并且Couchbase已配置,则Couchbase CacheManager
将自动配置。可以通过设置spring.cache.cache-name
属性在启动时创建额外的缓存,并且可以使用spring.cache.Couchbase.*
属性配置缓存默认值。例如,以下配置创建的cache1
和cache2
缓存的条目过期为10分钟:
spring.cache.cache-names=cache1,cache2
spring.cache.couchbase.expiration=10m
如果您需要对配置进行更多控制,可以考虑注册一个CouchbaseCacheManagerBuilderCustomizer
Bean。以下示例显示为cache1
和cache2
配置特定条目过期的定制器:
@Configuration(proxyBeanMethods = false) public class MyCouchbaseCacheManagerConfiguration { @Bean public CouchbaseCacheManagerBuilderCustomizer myCouchbaseCacheManagerBuilderCustomizer() { return (builder) -> builder .withCacheConfiguration("cache1", CouchbaseCacheConfiguration .defaultCacheConfig().entryExpiry(Duration.ofSeconds(10))) .withCacheConfiguration("cache2", CouchbaseCacheConfiguration .defaultCacheConfig().entryExpiry(Duration.ofMinutes(1))); } }
1.1.6. Redis
如果Redis可用并已配置,则会自动配置RedisCacheManager
。可以通过设置spring.cache.cache-name
属性在启动时创建额外的缓存,并且可以使用spring.cache.redis.*
属性配置缓存默认值。例如,以下配置创建的cache1
和cache2
缓存的生存时间为10分钟:
spring.cache.cache-names=cache1,cache2
spring.cache.redis.time-to-live=10m
By default, a key prefix is added so that, if two separate caches use the same key, Redis does not have overlapping keys and cannot return invalid values. We strongly recommend keeping this setting enabled if you create your own RedisCacheManager . |
You can take full control of the default configuration by adding a RedisCacheConfiguration @Bean of your own. This can be useful if you need to customize the default serialization strategy. |
如果您需要对配置进行更多控制,可以考虑注册一个RedisCacheManagerBuilderCustomizer
Bean。以下示例显示为cache1
和cache2
配置特定生存时间的定制器:
@Configuration(proxyBeanMethods = false) public class MyRedisCacheManagerConfiguration { @Bean public RedisCacheManagerBuilderCustomizer myRedisCacheManagerBuilderCustomizer() { return (builder) -> builder .withCacheConfiguration("cache1", RedisCacheConfiguration .defaultCacheConfig().entryTtl(Duration.ofSeconds(10))) .withCacheConfiguration("cache2", RedisCacheConfiguration .defaultCacheConfig().entryTtl(Duration.ofMinutes(1))); } }
1.1.7. Caffeine
Caffeine是对Guava缓存的Java 8重写,取代了对Guava的支持。如果存在咖啡因,则会自动配置CaffeineCacheManager
(由Spring-ot-starter-cache
“starter”提供)。可以在启动时通过设置spring.cache.cache-name
属性来创建缓存,并且可以通过以下方法之一(按指定的顺序)自定义缓存:
-
由
spring.cache.caffeine.spec
定义的缓存规范 -
定义了
com.github.benmanes.caffeine.cache.CaffeineSpec
Bean -
定义了
com.github.benmanes.caffeine.cache.Caffeine
Bean
例如,以下配置创建的cache1
和cache2
缓存的最大大小为500,生存时间为10分钟
spring.cache.cache-names=cache1,cache2
spring.cache.caffeine.spec=maximumSize=500,expireAfterAccess=600s
如果定义了CaffeineCacheManager Bean,它将自动与<com.github.benmanes.caffeine.cache.CacheLoader
>CaffeineCacheManager关联。由于CacheLoader
将与由缓存管理器管理的所有缓存相关联,因此必须将其定义为CacheLoader<;Object;
。自动配置会忽略任何其他泛型类型。
1.1.8. Cache2k
Cache2k是内存缓存。如果存在Cache2k Spring集成,则会自动配置SpringCache2kCacheManager
。
通过设置spring.cache.cache-name
属性,可以在启动时创建缓存。可以使用Cache2kBuilderCustomizer
Bean来自定义缓存默认设置。以下示例显示一个定制器,该定制器将缓存容量配置为200个条目,过期时间为5分钟:
@Configuration(proxyBeanMethods = false) public class MyCache2kDefaultsConfiguration { @Bean public Cache2kBuilderCustomizer myCache2kDefaultsCustomizer() { return (builder) -> builder.entryCapacity(200) .expireAfterWrite(5, TimeUnit.MINUTES); } }
1.1.9. Simple
如果找不到其他提供程序,则配置一个使用ConcurentHashMap
作为缓存存储的简单实现。如果应用程序中不存在缓存库,则这是默认设置。默认情况下,缓存是根据需要创建的,但您可以通过设置缓存名称
属性来限制可用缓存列表。例如,如果只需要cache1
和cache2
缓存,请按如下方式设置cache1
cache2属性:
spring.cache.cache-names=cache1,cache2
如果您这样做了,并且您的应用程序使用了未列出的缓存,则它在运行时会在需要缓存时失败,但不会在启动时失败。这类似于使用未声明缓存时“真正的”缓存提供程序的行为方式。
2. Hazelcast
如果类路径上有Hazelcast并且找到了合适的配置,则Spring Boot会自动配置您可以注入到应用程序中的Hazelcast实例
。
Spring Boot首先尝试通过检查以下配置选项来创建客户端:
-
com.hazelcast.client.config.ClientConfig
Bean的存在。 -
由
spring.hazelCast.config
属性定义的配置文件。 -
存在
hazelCast.client.config
系统属性。 -
工作目录或类路径根目录中的
Hazelcast-client.xml
。 -
工作目录或类路径根目录中的
Hazelcast-client.yaml
(或Hazelcast-client.yml
)。
如果无法创建客户端,则Spring Boot会尝试配置嵌入式服务器。如果您定义com.hazelCast.config.Config
Bean,则Spring Boot将使用该Bean。如果您的配置定义了实例名称,则Spring Boot会尝试定位现有实例,而不是创建新实例。
您还可以通过配置指定要使用的Hazelcast配置文件,如下例所示:
spring.hazelcast.config=classpath:config/my-hazelcast.xml
否则,Spring Boot会尝试从默认位置查找Hazelcast配置:工作目录或类路径根目录中的hazelCast.xml
,或相同位置中的.yaml
/.yml
。我们还检查是否设置了hazelCast.config
系统属性。有关详细信息,请参阅Hazelcast文档。
By default, @SpringAware on Hazelcast components is supported. The ManagementContext can be overridden by declaring a HazelcastConfigCustomizer bean with an @Order higher than zero. |
Spring Boot also has explicit caching support for Hazelcast. If caching is enabled, the HazelcastInstance is automatically wrapped in a CacheManager implementation. |
3. Quartz Scheduler
Spring Boot为使用Quartz调度器提供了几个便利,包括Spring-ot-starter-Quartz
“starter”。如果Quartz可用,则自动配置Scheduler
(通过SchedulerFactoryBean
抽象)。
以下类型的Bean将自动拾取并与Scheduler
关联:
-
JobDetail
:定义特定的作业。JobDetail
实例可以使用JobBuilder
接口构建。 -
日历
。 -
触发器
:定义触发特定作业的时间。
默认情况下,使用内存中的JobStore
。但是,如果应用程序中有DataSource
Bean并且相应地配置了spring.Quartz.job-store-type
属性,则可以配置基于JDBC的存储,如下例所示:
spring.quartz.job-store-type=jdbc
使用JDBC存储时,可以在启动时初始化架构,如下例所示:
spring.quartz.jdbc.initialize-schema=always
By default, the database is detected and initialized by using the standard scripts provided with the Quartz library. These scripts drop existing tables, deleting all triggers on every restart. It is also possible to provide a custom script by setting the spring.quartz.jdbc.schema property. |
若要使Quartz使用应用程序主DataSource
以外的DataSource
,请声明一个DataSource
Bean,并使用@QuartzDataSource
注释其@Bean
方法。这样做可以确保SchedulerFactoryBean
和架构初始化都使用特定于Quartz的DataSource
。同样,为了让Quartz使用应用程序主TransactionManager
之外的TransactionManager
,请声明一个TransactionManager
Bean,并用@QuartzTransactionManager
注释其@Bean
方法。
默认情况下,配置创建的作业不会覆盖已从永久作业存储中读取的已注册作业。若要覆盖现有作业定义,请设置spring.quartz.overwrite-existing-jobs
属性。
Quartz Scheduler配置可以使用spring.Quartz
属性和SchedulerFactoryBeanCustomizer
Bean进行自定义,它们允许编程SchedulerFactoryBean
自定义。高级Quartz配置属性可以使用spring.Quartz.Properties.*
进行自定义。
In particular, an Executor bean is not associated with the scheduler as Quartz offers a way to configure the scheduler through spring.quartz.properties . If you need to customize the task executor, consider implementing SchedulerFactoryBeanCustomizer . |
作业可以定义设置器以注入数据映射属性。常规Bean也可以以类似的方式注入,如下例所示:
public class MySampleJob extends QuartzJobBean { // Inject "MyService" bean public void setMyService(MyService myService) { this.myService = myService; } // Inject the "name" job data property public void setName(String name) { this.name = name; } @Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { this.myService.someMethod(context.getFireTime(), this.name); } }
4. Sending Email
Spring框架提供了使用JavaMailSender
接口发送电子邮件的抽象,而Spring Boot为其提供了自动配置以及一个启动模块。
See the reference documentation for a detailed explanation of how you can use JavaMailSender . |
如果spring.mail.host
和相关的库(由Spring-ot-starter-mail
定义)可用,则会创建一个默认的JavaMailSender
。发送者可以通过spring.mail
命名空间中的配置项进一步定制。有关详细信息,请参阅MailProperties
。
特别是,某些默认超时值是无限的,您可能希望对其进行更改,以避免无响应的邮件服务器阻止线程,如下例所示:
spring.mail.properties[mail.smtp.connectiontimeout]=5000
spring.mail.properties[mail.smtp.timeout]=3000
spring.mail.properties[mail.smtp.writetimeout]=5000
还可以使用JNDI中的现有会话
配置Java MailSender
:
spring.mail.jndi-name=mail/Session
当设置了jndi-name
时,它优先于所有其他与会话相关的设置。
5. Validation
只要类路径上有JSR-303实现(比如Hibernate验证器),就会自动启用Bean验证1.1支持的方法验证特性。这允许在Bean方法的参数和/或返回值上使用javax.valify
约束进行注释。对于要在其方法中搜索内联约束批注的目标类,需要在类型级别使用@valated
批注来批注具有此类批注的目标类。
例如,以下服务触发第一个参数的验证,确保其大小在8到10之间:
@Service @Validated public class MyBean { public Archive findByCodeAndAuthor(@Size(min = 8, max = 10) String code, Author author) { return ... } }
解析约束消息中的{PARAMETERS}
时使用应用程序的MessageSource
。这允许您使用应用程序的Messages.Properties
文件来处理Bean验证消息。一旦解析了参数,就可以使用Bean验证的默认插值器来完成消息插补。
要定制用于构建<代码>ValidatorFactory
ValidationConfigurationCustomizer>的<代码>配置
,请定义一个ValidatorFactory Bean。当定义了多个定制器Bean时,将根据它们的@order
注释或有序
实现按顺序调用它们。
6. Calling REST Services
如果您的应用程序调用远程REST服务,那么Spring Boot使用RestTemplate
或WebClient
非常方便。
6.1. RestTemplate
如果需要从应用程序调用远程REST服务,可以使用Spring框架的RestTemplate
类。由于RestTemplate
实例在使用前通常需要进行定制,因此Spring Boot不提供任何自动配置的RestTemplate
Bean。但是,它会自动配置RestTemplateBuilder
,在需要时可用来创建RestTemplateBuilder
实例。自动配置的RestTemplateBuilder
确保将合理的HttpMessageConverters
应用于RestTemplateBuilder
实例。
下面的代码显示了一个典型的示例:
@Service public class MyService { private final RestTemplate restTemplate; public MyService(RestTemplateBuilder restTemplateBuilder) { this.restTemplate = restTemplateBuilder.build(); } public Details someRestCall(String name) { return this.restTemplate.getForObject("/{name}/details", Details.class, name); } }
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.basicAuthentication("user", "password").build() . |
6.1.1. RestTemplate Customization
有三种主要方法可用于RestTemplate
自定义,具体取决于您希望自定义应用的范围有多广。
为了尽可能缩小任何定制的范围,注入自动配置的RestTemplateBuilder
,然后根据需要调用它的方法。每个方法调用都返回一个新的RestTemplateBuilder
实例,因此定制只影响生成器的这次使用。
要进行应用程序范围的累加性定制,请使用RestTemplateCustomizer
Bean。所有此类Bean都自动注册到自动配置的RestTemplateBuilder
,并应用于使用它构建的任何模板。
以下示例显示了为除192.168.0.5
以外的所有主机配置代理使用的定制器:
public class MyRestTemplateCustomizer implements RestTemplateCustomizer { @Override public void customize(RestTemplate restTemplate) { HttpRoutePlanner routePlanner = new CustomRoutePlanner(new HttpHost("proxy.example.com")); HttpClient httpClient = HttpClientBuilder.create().setRoutePlanner(routePlanner).build(); restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory(httpClient)); } static class CustomRoutePlanner extends DefaultProxyRoutePlanner { CustomRoutePlanner(HttpHost proxy) { super(proxy); } @Override protected HttpHost determineProxy(HttpHost target, HttpContext context) throws HttpException { if (target.getHostName().equals("192.168.0.5")) { return null; } return super.determineProxy(target, context); } } }
最后,您可以定义自己的RestTemplateBuilder
Bean。这样做将替换自动配置的构建器。如果您希望将任何RestTemplateCustomizer
Bean应用于您的定制构建器,就像自动配置所做的那样,使用RestTemplateBuilderConfigurer
配置它。下面的示例公开了一个RestTemplateBuilder
,该RestTemplateBuilder
与Spring Boot的自动配置所做的操作相匹配,只是还指定了自定义连接和读取超时:
@Configuration(proxyBeanMethods = false) public class MyRestTemplateBuilderConfiguration { @Bean public RestTemplateBuilder restTemplateBuilder(RestTemplateBuilderConfigurer configurer) { return configurer.configure(new RestTemplateBuilder()).setConnectTimeout(Duration.ofSeconds(5)) .setReadTimeout(Duration.ofSeconds(2)); } }
最极端(也是很少使用)的选择是在不使用配置器的情况下创建您自己的RestTemplateBuilder
Bean。除了替换自动配置的构建器之外,这还防止使用任何RestTemplateCustomizer
Bean。
6.2. WebClient
如果您的类路径上有Spring WebFlux,您还可以选择使用WebClient
来调用远程REST服务。与RestTemplate
相比,该客户端具有更多的功能,并且完全是反应性的。您可以在Spring框架文档的专用部分中了解更多关于WebClient
的信息。
Spring Boot为您创建和预配置WebClient.Builder
。强烈建议将其注入到您的组件中,并使用它来创建WebClient
实例。Spring Boot正在配置构建器以共享HTTP资源,以与服务器相同的方式反映编解码器设置(请参阅WebFlux HTTP编解码器自动配置),等等。
下面的代码显示了一个典型的示例:
@Service public class MyService { private final WebClient webClient; public MyService(WebClient.Builder webClientBuilder) { this.webClient = webClientBuilder.baseUrl("https://example.org").build(); } public Mono<Details> someRestCall(String name) { return this.webClient.get().uri("/{name}/details", name).retrieve().bodyToMono(Details.class); } }
6.2.1. WebClient Runtime
Spring Boot将自动检测使用哪个ClientHttpConnector
来驱动WebClient
,这取决于应用程序类路径上可用的库。目前,支持反应器Netty、Jetty RS客户端、ApacheHttpClient和JDK的HttpClient。
Spring-Boot-starter-WebFlux
starter默认依赖于io.projectreactor.netty:reactor-netty
,它同时提供了服务器和客户端实现。如果您选择使用Jetty作为反应式服务器,则应该添加对Jetty反应式HTTP客户端库org.eclipse.jetty:jetty-reactive-httpclient
.的依赖对服务器和客户端使用相同的技术有其优势,因为它将自动在客户端和服务器之间共享HTTP资源。
开发人员可以通过提供定制的ReacterResourceFactory
或JettyResourceFactory
Bean来覆盖Jetty和反应器Netty的资源配置--这将同时应用于客户端和服务器。
如果您希望覆盖客户端选择,您可以定义自己的ClientHttpConnector并完全控制客户端配置。
您可以在Spring框架参考文档中了解有关WebClient
配置选项的更多信息。
6.2.2. WebClient Customization
有三种主要方法可用于WebClient
自定义,具体取决于您希望自定义应用的范围有多广。
为了尽可能缩小任何定制的范围,注入自动配置的WebClient.Builder
,然后根据需要调用它的方法。WebClient.Builder
实例是有状态的:构建器上的任何更改都会反映在随后使用它创建的所有客户端中。如果您希望使用相同的构建器创建多个客户端,还可以考虑使用WebClient.Builder Other=Builder.clone();
来克隆构建器。
要对所有WebClient.Builder
实例进行应用程序范围的累加性定制,您可以声明WebClientCustomizer
Bean并在注入点本地更改WebClient.Builder
。
最后,您可以回退到原来的API并使用WebClient.create()
。在这种情况下,不会应用自动配置或WebClientCustomizer
。
7. Web Services
Spring Boot提供了Web服务自动配置,因此您所要做的就是定义您的端点
。
Spring Web Services特性可以通过Spring-ot-starter-webservices
模块轻松访问。
SimpleWsdl11Definition
和SimpleXsdSchema
可以分别为您的WSDL和XSD自动创建Bean。要执行此操作,请配置它们的位置,如下例所示:
spring.webservices.wsdl-locations=classpath:/wsdl
7.1. Calling Web Services with WebServiceTemplate
如果需要从应用程序调用远程Web服务,可以使用WebServiceTemplate
类。由于WebServiceTemplate
实例在使用前通常需要进行定制,因此Spring Boot不提供任何自动配置的WebServiceTemplate
Bean。但是,它会自动配置一个WebServiceTemplateBuilder
,在需要时可以用它来创建WebServiceTemplate
实例。
下面的代码显示了一个典型的示例:
@Service public class MyService { private final WebServiceTemplate webServiceTemplate; public MyService(WebServiceTemplateBuilder webServiceTemplateBuilder) { this.webServiceTemplate = webServiceTemplateBuilder.build(); } public SomeResponse someWsCall(SomeRequest detailsReq) { return (SomeResponse) this.webServiceTemplate.marshalSendAndReceive(detailsReq, new SoapActionCallback("https://ws.example.com/action")); } }
默认情况下,WebServiceTemplateBuilder
使用类路径上可用的HTTP客户端库检测合适的基于HTTP的WebServiceMessageSender
。您还可以按如下方式自定义读取和连接超时:
@Configuration(proxyBeanMethods = false) public class MyWebServiceTemplateConfiguration { @Bean public WebServiceTemplate webServiceTemplate(WebServiceTemplateBuilder builder) { WebServiceMessageSender sender = new HttpWebServiceMessageSenderBuilder() .setConnectTimeout(Duration.ofSeconds(5)) .setReadTimeout(Duration.ofSeconds(2)) .build(); return builder.messageSenders(sender).build(); } }
8. Distributed Transactions With JTA
通过使用从JNDI检索的事务管理器,Spring Boot支持跨多个XA资源的分布式JTA事务。
当检测到JTA环境时,将使用Spring的JtaTransactionManager
来管理事务。升级了自动配置的JMS、数据源和JPA Bean以支持XA事务。您可以使用标准的Spring习惯用法,如@Transaction
来参与分布式事务。如果您处于JTA环境中,并且仍然希望使用本地事务,则可以将spring.jta.Enabled
属性设置为FALSE
以禁用JTA自动配置。
8.1. Using a Jakarta EE Managed Transaction Manager
如果将Spring Boot应用程序打包为war
或ear
文件并将其部署到Jakarta EE应用服务器,则可以使用应用服务器的内置事务管理器。Spring Boot试图通过查看常见的JNDI位置(Java:comp/UserTransaction
、Java:comp/TransactionManager
等)来自动配置事务管理器。在使用应用程序服务器提供的事务服务时,您通常还希望确保所有资源都由服务器管理并通过JNDI公开。Href=“0”>spring.datasource.jndi-name
Boot试图通过在JNDI路径(<代码>Java:/JmsXA
或<代码>Java:/XAConnectionFactory
)中查找<代码>ConnectionFactory
来自动配置JMS,并且您可以使用spring.datasource.jndi-name
属性来配置<代码>数据源
。
8.2. Mixing XA and Non-XA JMS Connections
在使用JTA时,主要JMSConnectionFactory
Bean支持XA并参与分布式事务。您可以在不使用任何@限定符
的情况下向Bean注入:
public MyBean(ConnectionFactory connectionFactory) {
// ...
}
在某些情况下,您可能希望使用非XAConnectionFactory
来处理某些JMS消息。例如,您的JMS处理逻辑可能需要比XA超时更长的时间。
如果您想使用非XAConnectionFactory
,您可以使用non XaJmsConnectionFactory
Bean:
public MyBean(@Qualifier("nonXaJmsConnectionFactory") ConnectionFactory connectionFactory) {
// ...
}
为了保持一致性,还使用了Bean别名xaJmsConnectionFactory
来提供jmsConnectionFactory
:
public MyBean(@Qualifier("xaJmsConnectionFactory") ConnectionFactory connectionFactory) {
// ...
}
8.3. Supporting an Embedded Transaction Manager
XAConnectionFactoryWrapper
和XADataSourceWrapper
接口可用于支持嵌入式事务管理器。这些接口负责包装XAConnectionFactory
和XADataSource
Bean,并将它们公开为常规的ConnectionFactory
和DataSource
Bean,它们透明地注册到分布式事务中。DataSource和JMS自动配置使用JTA变体,前提是您在ApplicationContext
中注册了JtaTransactionManager
Bean和适当的XA包装器Bean。