Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 671ff44

Browse files
committed
Add 34-38 sections
1 parent 1d848d1 commit 671ff44

File tree

2 files changed

+258
-5
lines changed

2 files changed

+258
-5
lines changed

SUMMARY.md

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -258,11 +258,19 @@
258258
- [33.3.2、接收消息](pages/spring-boot-features.md#boot-features-kafka-receiving-a-message)
259259
- [33.3.3、Kafka Stream](pages/spring-boot-features.md#boot-features-kafka-streams)
260260
- [33.3.4、其他 Kafka 属性](pages/spring-boot-features.md#boot-features-kafka-extra-props)
261-
- 34、使用 `RestTemplate` 调用 REST 服务
262-
- 35、使用 `WebClient` 调用 REST 服务
263-
- 36、验证
264-
- 37、发送邮件
265-
- 38、JTA 分布式事务
261+
- [34、使用 `RestTemplate` 调用 REST 服务](pages/spring-boot-features.md#boot-features-resttemplate)
262+
- [34.1、自定义 RestTemplate](pages/spring-boot-features.md#boot-features-resttemplate-customization)
263+
- [34、使用 `RestTemplate` 调用 REST 服务](pages/spring-boot-features.md#boot-features-resttemplate)
264+
- [35、使用 `WebClient` 调用 REST 服务](pages/spring-boot-features.md#boot-features-webclient)
265+
- [35.1、WebClient 运行时](pages/spring-boot-features.md#boot-features-webclient-runtime)
266+
- [35.2、自定义 WebClient](pages/spring-boot-features.md#boot-features-webclient-customization)
267+
- [36、验证](pages/spring-boot-features.md#boot-features-validation)
268+
- [37、发送邮件](pages/spring-boot-features.md#boot-features-email)
269+
- [38、JTA 分布式事务](pages/spring-boot-features.md#boot-features-jta)
270+
- [38.1、使用 Atomikos 事务管理器](pages/spring-boot-features.md#boot-features-jta-atomikos)
271+
- [38.2、使用 Bitronix 事务管理器](pages/spring-boot-features.md#boot-features-jta-bitronix)
272+
- [38.3、使用 Java EE 管理的事务管理器](pages/spring-boot-features.md#boot-features-jta-javaee)
273+
- [38.4、混合使用 XA 与非 XA JMS 连接](pages/spring-boot-features.md#boot-features-jta-mixed-jms)
266274
- 39、Hazelcast
267275
- 40、Quartz 调度器
268276
- 41、任务执行与调度

pages/spring-boot-features.md

Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4402,4 +4402,249 @@ spring.kafka.producer.properties.spring.json.add.type.headers=false
44024402

44034403
> 以这种方式设置的属性将覆盖 Spring Boot 明确支持的任何配置项。
44044404
4405+
<a id="boot-features-resttemplate"></a>
4406+
4407+
## 34、使用 `RestTemplate` 调用 REST 服务
4408+
4409+
如果您的应用程序需要调用远程 REST 服务,这可以使用 Spring Framework 的 [`RestTemplate`](https://docs.spring.io/spring/docs/5.1.3.RELEASE/javadoc-api/org/springframework/web/client/RestTemplate.html) 类。由于 `RestTemplate` 实例在使用之前通常需要进行自定义,因此 Spring Boot 不提供任何自动配置的 `RestTemplate` bean。但是,它会自动配置 `RestTemplateBuilder`,可在需要时创建 `RestTemplate` 实例。自动配置的 `RestTemplateBuilder` 确保将合适的 `HttpMessageConverters` 应用于 `RestTemplate` 实例。
4410+
4411+
以下代码展示了一个典型示例:
4412+
4413+
```java
4414+
@Service
4415+
public class MyService {
4416+
4417+
private final RestTemplate restTemplate;
4418+
4419+
public MyService(RestTemplateBuilder restTemplateBuilder) {
4420+
this.restTemplate = restTemplateBuilder.build();
4421+
}
4422+
4423+
public Details someRestCall(String name) {
4424+
return this.restTemplate.getForObject("/{name}/details", Details.class, name);
4425+
}
4426+
4427+
}
4428+
```
4429+
4430+
**提示**
4431+
4432+
> `RestTemplateBuilder` 包含许多可用于快速配置 ·RestTemplate· 的方法。例如,要添加 BASIC auth 支持,可以使用 `builder.basicAuthentication("user", "password").build()`
4433+
4434+
<a id="boot-features-resttemplate-customization"></a>
4435+
4436+
### 34.1、自定义 RestTemplate
4437+
4438+
`RestTemplate` 自定义有三种主要方法,具体取决于您希望自定义的程度。
4439+
4440+
要想自定义的范围尽可能地窄,请注入自动配置的 `RestTemplateBuilder`,然后根据需要调用其方法。每个方法调用都返回一个新的 `RestTemplateBuilder` 实例,因此自定义只会影响当前构建器。
4441+
4442+
要在应用程序范围内添加自定义配置,请使用 `RestTemplateCustomizer` bean。所有这些 bean 都会自动注册到自动配置的 `RestTemplateBuilder`,并应用于使用它构建的所有模板。
4443+
4444+
以下示例展示了一个 customizer,它为除 `192.168.0.5` 之外的所有主机配置代理:
4445+
4446+
```java
4447+
static class ProxyCustomizer implements RestTemplateCustomizer {
4448+
4449+
@Override
4450+
public void customize(RestTemplate restTemplate) {
4451+
HttpHost proxy = new HttpHost("proxy.example.com");
4452+
HttpClient httpClient = HttpClientBuilder.create()
4453+
.setRoutePlanner(new DefaultProxyRoutePlanner(proxy) {
4454+
4455+
@Override
4456+
public HttpHost determineProxy(HttpHost target,
4457+
HttpRequest request, HttpContext context)
4458+
throws HttpException {
4459+
if (target.getHostName().equals("192.168.0.5")) {
4460+
return null;
4461+
}
4462+
return super.determineProxy(target, request, context);
4463+
}
4464+
4465+
}).build();
4466+
restTemplate.setRequestFactory(
4467+
new HttpComponentsClientHttpRequestFactory(httpClient));
4468+
}
4469+
4470+
}
4471+
```
4472+
4473+
最后,最极端(也很少使用)的选择是创建自己的 `RestTemplateBuilder` bean。这样做会关闭 `RestTemplateBuilder` 的自动配置,并阻止使用任何 `RestTemplateCustomizer` bean。
4474+
4475+
<a id="boot-features-webclient"></a>
4476+
4477+
## 35、使用 `WebClient` 调用 REST 服务
4478+
4479+
如果在 classpath 上存在 Spring WebFlux,则还可以选择使用 `WebClient` 来调用远程 REST 服务。与 `RestTemplate` 相比,该客户端更具函数式风格并且完全响应式。您可以在 [Spring Framework 文档的相关部分](https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/web-reactive.html#webflux-client)中了解有关 `WebClient` 的更多信息。
4480+
4481+
Spring Boot 为您创建并预配置了一个 `WebClient.Builder`。强烈建议将其注入您的组件中并使用它来创建 `WebClient` 实例。Spring Boot 配置该构建器以共享 HTTP 资源,以与服务器相同的方式反射编解码器设置(请参阅 [WebFlux HTTP 编解码器自动配置](#boot-features-webflux-httpcodecs))等。
4482+
4483+
以下代码是一个典型示例:
4484+
4485+
```java
4486+
@Service
4487+
public class MyService {
4488+
4489+
private final WebClient webClient;
4490+
4491+
public MyService(WebClient.Builder webClientBuilder) {
4492+
this.webClient = webClientBuilder.baseUrl("http://example.org").build();
4493+
}
4494+
4495+
public Mono<Details> someRestCall(String name) {
4496+
return this.webClient.get().uri("/{name}/details", name)
4497+
.retrieve().bodyToMono(Details.class);
4498+
}
4499+
4500+
}
4501+
```
4502+
4503+
<a id="boot-features-webclient-runtime"></a>
4504+
4505+
### 35.1、WebClient 运行时
4506+
4507+
Spring Boot 将自动检测用于驱动 `WebClient``ClientHttpConnector`,具体取决于应用程序 classpath 上可用的类库。目前支持 Reactor Netty 和 Jetty RS 客户端。
4508+
4509+
默认情况下 `spring-boot-starter-webflux` starter 依赖于 `io.projectreactor.netty:reactor-netty`,它包含了服务器和客户端的实现。如果您选择将 `Jetty` 用作响应式服务器,则应添加 Jetty Reactive HTTP 客户端库依赖项 `org.eclipse.jetty:jetty-reactive-httpclient`。服务器和客户端使用相同的技术具有一定优势,因为它会自动在客户端和服务器之间共享 HTTP 资源。
4510+
4511+
开发人员可以通过提供自定义的 `ReactorResourceFactory``JettyResourceFactory` bean 来覆盖 Jetty 和 Reactor Netty 的资源配置 —— 这将同时应用于客户端和服务器。
4512+
4513+
如果您只希望覆盖客户端选项,则可以定义自己的 `ClientHttpConnector` bean 并完全控制客户端配置。
4514+
4515+
您可以在 [Spring Framework 参考文档中了解有关 `WebClient` 配置选项的更多信息](https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/web-reactive.html#webflux-client-builder)
4516+
4517+
<a id="boot-features-webclient-customization"></a>
4518+
4519+
### 35.2、自定义 WebClient
4520+
4521+
`WebClient` 自定义有三种主要方法,具体取决于您希望自定义的程度。
4522+
4523+
要想自定义的范围尽可能地窄,请注入自动配置的 `WebClient.Builder`,然后根据需要调用其方法。`WebClient.Builder` 实例是有状态的:构建器上的任何更改都会影响到之后所有使用它创建的客户端。如果要使用相同的构建器创建多个客户端,可以考虑使用 `WebClient.Builder other = builder.clone();` 的方式克隆构建器。
4524+
4525+
要在应用程序范围内对所有 `WebClient.Builder` 实例添加自定义,可以声明 `WebClientCustomizer` bean 并在注入点局部更改 `WebClient.Builder`
4526+
4527+
最后,您可以回退到原始 API 并使用 `WebClient.create()`。在这种情况下,不会应用自动配置或 `WebClientCustomizer`
4528+
4529+
<a id="boot-features-validation"></a>
4530+
4531+
## 36、验证
4532+
4533+
只要 classpath 上存在 JSR-303 实现(例如 Hibernate 验证器),就会自动启用 Bean Validation 1.1 支持的方法验证功能。这允许 bean 方法在其参数和/或返回值上使用 `javax.validation` 约束进行注解。带有此类注解方法的目标类需要在类级别上使用 `@Validated` 进行注解,以便搜索其内联约束注解的方法。
4534+
4535+
例如,以下服务触发第一个参数的验证,确保其大小在 8 到 10 之间:
4536+
4537+
```java
4538+
@Service
4539+
@Validated
4540+
public class MyBean {
4541+
4542+
public Archive findByCodeAndAuthor(@Size(min = 8, max = 10) String code,
4543+
Author author) {
4544+
...
4545+
}
4546+
4547+
}
4548+
```
4549+
4550+
<a id="boot-features-email"></a>
4551+
4552+
## 37、发送邮件
4553+
4554+
Spring Framework 提供了一个使用 `JavaMailSender` 接口发送电子邮件的简单抽象,Spring Boot 为其提供了自动配置以及一个 starter 模块。
4555+
4556+
**提示**
4557+
4558+
> 有关如何使用 `JavaMailSender` 的详细说明,请参阅[参考文档](https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/integration.html#mail)
4559+
4560+
如果 `spring.mail.host` 和相关库(由 `spring-boot-starter-mail` 定义)可用,则创建默认的 `JavaMailSender`(如果不存在)。可以通过 `spring.mail` 命名空间中的配置项进一步自定义发件人。有关更多详细信息,请参阅 [`MailProperties`](https://github.com/spring-projects/spring-boot/tree/v2.1.1.RELEASE/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailProperties.java)
4561+
4562+
特别是,某些默认超时时间的值是无限的,您可能想更改它以避免线程被无响应的邮件服务器阻塞,如下示例所示:
4563+
4564+
```ini
4565+
spring.mail.properties.mail.smtp.connectiontimeout=5000
4566+
spring.mail.properties.mail.smtp.timeout=3000
4567+
spring.mail.properties.mail.smtp.writetimeout=5000
4568+
```
4569+
4570+
也可以使用 JNDI 中的现有 `Session` 配置一个 `JavaMailSender`
4571+
4572+
```ini
4573+
spring.mail.jndi-name=mail/Session
4574+
```
4575+
4576+
设置 `jndi-name` 时,它优先于所有其他与 `Session` 相关的设置。
4577+
4578+
<a id="boot-features-jta"></a>
4579+
4580+
## 38、JTA 分布式事务
4581+
4582+
Spring Boot 通过使用 [Atomikos](http://www.atomikos.com/)[Bitronix](https://github.com/bitronix/btm) 嵌入式事务管理器来支持跨多个 XA 资源的分布式 JTA 事务。部署在某些 Java EE 应用服务器(Application Server)上也支持 JTA 事务。
4583+
4584+
当检测到 JTA 环境时,Spring 的 `JtaTransactionManager` 将用于管理事务。自动配置的 JMS、DataSource 和 JPA bean 已升级为支持 XA 事务。您可以使用标准的 Spring 方式(例如 `@Transactional`)来使用分布式事务。如果您处于 JTA 环境中并且仍想使用本地事务,则可以将 `spring.jta.enabled` 属性设置为 `false` 以禁用 JTA 自动配置。
4585+
4586+
<a id="boot-features-jta-atomikos"></a>
4587+
4588+
### 38.1、使用 Atomikos 事务管理器
4589+
4590+
[Atomikos](https://www.atomikos.com/) 是一个流行的开源事务管理器,可以嵌入到 Spring Boot 应用程序中。您可以使用 `spring-boot-starter-jta-atomikos` starter 来获取相应的 Atomikos 库。Spring Boot 自动配置 Atomikos 并确保将合适的依赖设置应用于 Spring bean,以确保启动和关闭顺序正确。
4591+
4592+
默认情况下,Atomikos 事务日志将写入应用程序主目录(应用程序 jar 文件所在的目录)中的 `transaction-logs` 目录。您可以通过在 `application.properties` 文件中设置 `spring.jta.log-dir` 属性来自定义此目录的位置。也可用 `spring.jta.atomikos.properties` 开头的属性来自定义 Atomikos `UserTransactionServiceImp`。有关完整的详细信息,请参阅 [AtomikosProperties Javadoc](https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/api/org/springframework/boot/jta/atomikos/AtomikosProperties.html)
4593+
4594+
**注意**
4595+
4596+
> 为确保多个事务管理器可以安全地协调相同的资源管理器,必须为每个 Atomikos 实例配置唯一 ID。默认情况下,此 ID 是运行 Atomikos 的计算机的 IP 地址。在生产环境中要确保唯一性,应为应用程序的每个实例配置 `spring.jta.transaction-manager-id` 属性,并使用不同的值。
4597+
4598+
<a id="boot-features-jta-bitronix"></a>
4599+
4600+
### 38.2、使用 Bitronix 事务管理器
4601+
4602+
[Bitronix](https://github.com/bitronix/btm) 是一个流行的开源 JTA 事务管理器实现。您可以使用 `spring-boot-starter-jta-bitronix` starter 为您的项目添加合适的 Bitronix 依赖。与 Atomikos 一样,Spring Boot 会自动配置 Bitronix 并对 bean 进行后处理(post-processes),以确保启动和关闭顺序正确。
4603+
4604+
默认情况下,Bitronix 事务日志文件(`part1.btm``part2.btm`)将写入应用程序主目录中的 `transaction-logs` 目录。您可以通过设置 `spring.jta.log-dir` 属性来自定义此目录的位置。以 `spring.jta.bitronix.properties` 开头的属性绑定到了 `bitronix.tm.Configuration` bean,允许完全自定义。有关详细信息,请参阅 [Bitronix 文档](https://github.com/bitronix/btm/wiki/Transaction-manager-configuration)
4605+
4606+
**注意**
4607+
4608+
> 为确保多个事务管理器能够安全地协调相同的资源管理器,必须为每个 Bitronix 实例配置唯一的 ID。默认情况下,此 ID 是运行 Bitronix 的计算机的 IP 地址。生产环境要确保唯一性,应为应用程序的每个实例配置 `spring.jta.transaction-manager-id` 属性,并使用不同的值。
4609+
4610+
<a id="boot-features-jta-javaee"></a>
4611+
4612+
### 38.3、使用 Java EE 管理的事务管理器
4613+
4614+
如果将 Spring Boot 应用程序打包为 `war``ear` 文件并将其部署到 Java EE 应用程序服务器,则可以使用应用程序服务器的内置事务管理器。Spring Boot 尝试通过查找常见的 JNDI 位置(`java:comp/UserTransaction``java:comp/TransactionManager` 等)来自动配置事务管理器。如果使用应用程序服务器提供的事务服务,通常还需要确保所有资源都由服务器管理并通过 JNDI 暴露。Spring Boot 尝试通过在 JNDI 路径(`java:/JmsXA``java:/JmsXA`)中查找 `ConnectionFactory` 来自动配置 JMS,并且可以使用 [`spring.datasource.jndi-name` 属性](#boot-features-connecting-to-a-jndi-datasource)来配置 `DataSource`
4615+
4616+
<a id="boot-features-jta-mixed-jms"></a>
4617+
4618+
### 38.4、混合使用 XA 与非 XA JMS 连接
4619+
4620+
使用 JTA 时,主 JMS `ConnectionFactory` bean 可识别 XA 并参与分布式事务。在某些情况下,您可能希望使用非 XA `ConnectionFactory` 处理某些 JMS 消息。例如,您的 JMS 处理逻辑可能需要比 XA 超时时间更长的时间。
4621+
4622+
如果要使用非 XA `ConnectionFactory`,可以注入 `nonXaJmsConnectionFactory` bean 而不是 `@Primary` `jmsConnectionFactory` bean。为了保持一致性,提供的 `jmsConnectionFactory` bean 还需要使用 `xaJmsConnectionFactory` 别名。
4623+
4624+
以下示例展示了如何注入 `ConnectionFactory` 实例:
4625+
4626+
```java
4627+
// Inject the primary (XA aware) ConnectionFactory
4628+
@Autowired
4629+
private ConnectionFactory defaultConnectionFactory;
4630+
4631+
// Inject the XA aware ConnectionFactory (uses the alias and injects the same as above)
4632+
@Autowired
4633+
@Qualifier("xaJmsConnectionFactory")
4634+
private ConnectionFactory xaConnectionFactory;
4635+
4636+
// Inject the non-XA aware ConnectionFactory
4637+
@Autowired
4638+
@Qualifier("nonXaJmsConnectionFactory")
4639+
private ConnectionFactory nonXaConnectionFactory;
4640+
```
4641+
4642+
<a id="boot-features-jta-supporting-alternative-embedded"></a>
4643+
4644+
## 38.5、支持嵌入式事务管理器
4645+
4646+
[`XAConnectionFactoryWrapper`](https://github.com/spring-projects/spring-boot/tree/v2.1.1.RELEASE/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jms/XAConnectionFactoryWrapper.java)[`XADataSourceWrapper`](https://github.com/spring-projects/spring-boot/tree/v2.1.1.RELEASE/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/XADataSourceWrapper.java) 接口可用于支持其他嵌入式事务管理器。接口负责包装 `XAConnectionFactory``XADataSource` bean,并将它们公开为普通的 `ConnectionFactory``DataSource` bean,它们透明地加入分布式事务。`DataSource` 和 JMS 自动配置使用 JTA 变体,前提是您需要有一个 `JtaTransactionManager` bean 和在 `ApplicationContext` 中注册有的相应 XA 包装器(wrapper) bean。
4647+
4648+
[BitronixXAConnectionFactoryWrapper](https://github.com/spring-projects/spring-boot/tree/v2.1.1.RELEASE/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jta/bitronix/BitronixXAConnectionFactoryWrapper.java)[BitronixXADataSourceWrapper](https://github.com/spring-projects/spring-boot/tree/v2.1.1.RELEASE/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jta/bitronix/BitronixXADataSourceWrapper.java) 为如何编写 XA 包装器提供了很好示例。
4649+
44054650
**待续……**

0 commit comments

Comments
 (0)