SpringBoot之数据访问-远程调用!

B站影视 内地电影 2025-05-18 16:50 2

摘要:后端服务开发一般会远程调用第三方接口,Spring Boot也整合了远程REST服务调用方式。开发人员可以通过自定义配置定义RestTemplate类和WebClient类,从而进行第三方接口调用操作。

后端服务开发一般会远程调用第三方接口,Spring Boot也整合了远程REST服务调用方式。开发人员可以通过自定义配置定义RestTemplate类和WebClient类,从而进行第三方接口调用操作。

由于Spring Boot不提供RestTemplate自动配置,因此可以使用RestTemplate-Builder来创建RestTemplate实例,代码如下:

@Service

public class MyService {

private final RestTemplate restTemplate;

public MyService(RestTemplateBuilder restTemplateBuilder)

{

//创建RestTemplate

this.restTemplate = restTemplateBuilder.build;

}

public Details someRestCall(String name) {

//请求调用

return

this.restTemplate.getForObject("/{name}/details",

Details.class, name);

}

}

还可以通过自定义SimpleClientHttpRequestFactory的方式创建RestTemplate,代码如下:

@Configuration

public class RestTemplateConfig {

@Bean

public RestTemplate

restTemplate(ClientHttpRequestFactory factory) {

return new RestTemplate(factory); //创建

RestTemplate

}

@Bean

public ClientHttpRequestFactory

simpleClientHttpRequestFactory {

SimpleClientHttpRequestFactory factory = new

SimpleClient

HttpRequestFactory;

factory.setConnectTimeout(15000); //设置

连接超时

factory.setReadTimeout(5000); //设置

读取超时

return factory;

}

}

Spring框架从5.0开始引入了WebFlux,如果是WebFlux工程,可以使用WebClient类进行远程REST服务调用。相比RestTemplate,WebClient的功能更多,并且是纯异步交互的。在Spring Boot中推荐使用WebClient.Builder新建WebClient实例。

改造4.4.1节中的例子,代码如下:

@Service

public class MyService {

private final WebClient webClient;

public MyService(WebClient.Builder webClientBuilder) {

//创建WebClient

this.webClient =

webClientBuilder.baseUrl("https://example.

org").build;

}

public Mono someRestCall(String name) {

//通过WebClient进行调用

return this.webClient.get.uri("/{name}/details",

name)

.retrieve.bodyToMono(Details.class);

}

}

通过自定义生成WebClient,代码如下:

//自定义WebClient

@Data

@Configuration

@ConditionalOnProperty(name = "httpClient.connect.timeout")

public class WebClientConfig {

@Value("${HttpClient.connect.timeout:2000}")

private int connectTimeOut;

@Value("${httpClient.read.timeout:2000}")

private int readTimeOut;

@Value("${httpClient.write.timeout:2000}")

private int writeTimeout;

@Value("${httpClient.retry.times:2}")

private int retryTimes;

@Value("${httpClient.connpool.maxConns:16}")

private int maxConns;

@Value("${httpClient.connpool.workCounts:16}")

private int workCounts;

@Value("${httpClient.connpool.acquireTimeOut:1000}")

private int acquireTimeOut;

//声明ReactorResourceFactory

@Bean

@Primary

public ReactorResourceFactory resourceFactory {

ReactorResourceFactory factory = new

ReactorResourceFactory;

factory.setUseGlobalResources(false);

factory.setConnectionProvider(ConnectionProvider.builder

("httpClient").metrics(true).maxConnections(maxConns)

.pendingAcquireTimeout(Duration.ofMillis(acquireTimeOut)).

build);

factory.setLoopResources(LoopResources.create("httpClient",

workCounts, true));

return factory;

}

//定义Retry策略

@Bean

@Primary

@RefreshScope

public Retry retry {

return Retry.anyOf(ReadTimeoutException.class,

ConnectTimeout

Exception.class, WebClientResponseException.class)

.fixedBackoff(Duration.ZERO)

.retryMax(retryTimes)

//retry次数

.doOnRetry((exception) -> {

//异常日志

log.warn("Retried ,Exception is {}" +

exception);

});

}

//定义WebClient

@Bean

@Primary

@RefreshScope

public WebClient webClient(WebClient.Builder

builder,Reactor

ResourceFactory resourceFactory) {

Function mapper = client ->

client.tcpConfiguration(tcpClient ->

tcpClient.option(ChannelOption.CONNECT_TIMEOUT_

MILLIS, connectTimeOut)

//创建连接超时时间

.option(ChannelOption.TCP_NODELAY, true)

//连接策略

.doOnConnected(connection ->

{

connection.addHandlerLast(new Read

TimeoutHandler(readTimeOut, TimeUnit.MILLISECONDS));

connection.addHandlerLast(new Write

TimeoutHandler(writeTimeout, TimeUnit.MILLISECONDS));

}))

.headers(headerBuilder -> { //设置

header属性

headerBuilder.set("Accept

charset", "utf-8");

Encoding", "gzip,

x-gzip, deflate");

headerBuilder.set("ContentType",

"text/plain;

charset=utf-8");

}).keepAlive(true);

ClientHttpConnector connector = new

ReactorClientHttpConnector

(resourceFactory, mapper);

return builder.clientConnector(connector).build;

}

}

来源:大数据架构师

相关推荐