Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in / Register
Toggle navigation
S
spring-boot
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
DEMO
spring-boot
Commits
ba258390
Commit
ba258390
authored
Apr 12, 2021
by
Andy Wilkinson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Provide auto-configuration for using Apache HttpClient 5 with WebClient
Closes gh-26004
parent
17b79fb2
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
78 additions
and
12 deletions
+78
-12
build.gradle
spring-boot-project/spring-boot-autoconfigure/build.gradle
+1
-0
ClientHttpConnectorAutoConfiguration.java
...function/client/ClientHttpConnectorAutoConfiguration.java
+3
-2
ClientHttpConnectorConfiguration.java
...ive/function/client/ClientHttpConnectorConfiguration.java
+23
-7
ClientHttpConnectorAutoConfigurationTests.java
...ion/client/ClientHttpConnectorAutoConfigurationTests.java
+31
-2
build.gradle
spring-boot-project/spring-boot-dependencies/build.gradle
+20
-1
No files found.
spring-boot-project/spring-boot-autoconfigure/build.gradle
View file @
ba258390
...
@@ -56,6 +56,7 @@ dependencies {
...
@@ -56,6 +56,7 @@ dependencies {
optional
(
"org.apache.activemq:artemis-jms-client"
)
optional
(
"org.apache.activemq:artemis-jms-client"
)
optional
(
"org.apache.activemq:artemis-jms-server"
)
optional
(
"org.apache.activemq:artemis-jms-server"
)
optional
(
"org.apache.commons:commons-dbcp2"
)
optional
(
"org.apache.commons:commons-dbcp2"
)
optional
(
"org.apache.httpcomponents.client5:httpclient5"
)
optional
(
"org.apache.kafka:kafka-streams"
)
optional
(
"org.apache.kafka:kafka-streams"
)
optional
(
"org.apache.solr:solr-solrj"
)
optional
(
"org.apache.solr:solr-solrj"
)
optional
(
"org.apache.tomcat.embed:tomcat-embed-core"
)
optional
(
"org.apache.tomcat.embed:tomcat-embed-core"
)
...
...
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/function/client/ClientHttpConnectorAutoConfiguration.java
View file @
ba258390
/*
/*
* Copyright 2012-202
0
the original author or authors.
* Copyright 2012-202
1
the original author or authors.
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* you may not use this file except in compliance with the License.
...
@@ -40,7 +40,8 @@ import org.springframework.web.reactive.function.client.WebClient;
...
@@ -40,7 +40,8 @@ import org.springframework.web.reactive.function.client.WebClient;
*/
*/
@Configuration
(
proxyBeanMethods
=
false
)
@Configuration
(
proxyBeanMethods
=
false
)
@ConditionalOnClass
(
WebClient
.
class
)
@ConditionalOnClass
(
WebClient
.
class
)
@Import
({
ClientHttpConnectorConfiguration
.
ReactorNetty
.
class
,
ClientHttpConnectorConfiguration
.
JettyClient
.
class
})
@Import
({
ClientHttpConnectorConfiguration
.
ReactorNetty
.
class
,
ClientHttpConnectorConfiguration
.
JettyClient
.
class
,
ClientHttpConnectorConfiguration
.
HttpClient5
.
class
})
public
class
ClientHttpConnectorAutoConfiguration
{
public
class
ClientHttpConnectorAutoConfiguration
{
@Bean
@Bean
...
...
spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/function/client/ClientHttpConnectorConfiguration.java
View file @
ba258390
/*
/*
* Copyright 2012-202
0
the original author or authors.
* Copyright 2012-202
1
the original author or authors.
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* you may not use this file except in compliance with the License.
...
@@ -16,6 +16,8 @@
...
@@ -16,6 +16,8 @@
package
org
.
springframework
.
boot
.
autoconfigure
.
web
.
reactive
.
function
.
client
;
package
org
.
springframework
.
boot
.
autoconfigure
.
web
.
reactive
.
function
.
client
;
import
org.apache.hc.client5.http.impl.async.HttpAsyncClients
;
import
org.apache.hc.core5.http.nio.AsyncRequestProducer
;
import
org.eclipse.jetty.client.HttpClient
;
import
org.eclipse.jetty.client.HttpClient
;
import
org.eclipse.jetty.util.ssl.SslContextFactory
;
import
org.eclipse.jetty.util.ssl.SslContextFactory
;
...
@@ -26,6 +28,7 @@ import org.springframework.context.annotation.Bean;
...
@@ -26,6 +28,7 @@ import org.springframework.context.annotation.Bean;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Lazy
;
import
org.springframework.context.annotation.Lazy
;
import
org.springframework.http.client.reactive.ClientHttpConnector
;
import
org.springframework.http.client.reactive.ClientHttpConnector
;
import
org.springframework.http.client.reactive.HttpComponentsClientHttpConnector
;
import
org.springframework.http.client.reactive.JettyClientHttpConnector
;
import
org.springframework.http.client.reactive.JettyClientHttpConnector
;
import
org.springframework.http.client.reactive.JettyResourceFactory
;
import
org.springframework.http.client.reactive.JettyResourceFactory
;
import
org.springframework.http.client.reactive.ReactorClientHttpConnector
;
import
org.springframework.http.client.reactive.ReactorClientHttpConnector
;
...
@@ -45,17 +48,17 @@ class ClientHttpConnectorConfiguration {
...
@@ -45,17 +48,17 @@ class ClientHttpConnectorConfiguration {
@Configuration
(
proxyBeanMethods
=
false
)
@Configuration
(
proxyBeanMethods
=
false
)
@ConditionalOnClass
(
reactor
.
netty
.
http
.
client
.
HttpClient
.
class
)
@ConditionalOnClass
(
reactor
.
netty
.
http
.
client
.
HttpClient
.
class
)
@ConditionalOnMissingBean
(
ClientHttpConnector
.
class
)
@ConditionalOnMissingBean
(
ClientHttpConnector
.
class
)
public
static
class
ReactorNetty
{
static
class
ReactorNetty
{
@Bean
@Bean
@ConditionalOnMissingBean
@ConditionalOnMissingBean
public
ReactorResourceFactory
reactorClientResourceFactory
()
{
ReactorResourceFactory
reactorClientResourceFactory
()
{
return
new
ReactorResourceFactory
();
return
new
ReactorResourceFactory
();
}
}
@Bean
@Bean
@Lazy
@Lazy
public
ReactorClientHttpConnector
reactorClientHttpConnector
(
ReactorResourceFactory
reactorResourceFactory
,
ReactorClientHttpConnector
reactorClientHttpConnector
(
ReactorResourceFactory
reactorResourceFactory
,
ObjectProvider
<
ReactorNettyHttpClientMapper
>
mapperProvider
)
{
ObjectProvider
<
ReactorNettyHttpClientMapper
>
mapperProvider
)
{
ReactorNettyHttpClientMapper
mapper
=
mapperProvider
.
orderedStream
()
ReactorNettyHttpClientMapper
mapper
=
mapperProvider
.
orderedStream
()
.
reduce
((
before
,
after
)
->
(
client
)
->
after
.
configure
(
before
.
configure
(
client
)))
.
reduce
((
before
,
after
)
->
(
client
)
->
after
.
configure
(
before
.
configure
(
client
)))
...
@@ -68,17 +71,17 @@ class ClientHttpConnectorConfiguration {
...
@@ -68,17 +71,17 @@ class ClientHttpConnectorConfiguration {
@Configuration
(
proxyBeanMethods
=
false
)
@Configuration
(
proxyBeanMethods
=
false
)
@ConditionalOnClass
(
org
.
eclipse
.
jetty
.
reactive
.
client
.
ReactiveRequest
.
class
)
@ConditionalOnClass
(
org
.
eclipse
.
jetty
.
reactive
.
client
.
ReactiveRequest
.
class
)
@ConditionalOnMissingBean
(
ClientHttpConnector
.
class
)
@ConditionalOnMissingBean
(
ClientHttpConnector
.
class
)
public
static
class
JettyClient
{
static
class
JettyClient
{
@Bean
@Bean
@ConditionalOnMissingBean
@ConditionalOnMissingBean
public
JettyResourceFactory
jettyClientResourceFactory
()
{
JettyResourceFactory
jettyClientResourceFactory
()
{
return
new
JettyResourceFactory
();
return
new
JettyResourceFactory
();
}
}
@Bean
@Bean
@Lazy
@Lazy
public
JettyClientHttpConnector
jettyClientHttpConnector
(
JettyResourceFactory
jettyResourceFactory
)
{
JettyClientHttpConnector
jettyClientHttpConnector
(
JettyResourceFactory
jettyResourceFactory
)
{
SslContextFactory
sslContextFactory
=
new
SslContextFactory
.
Client
();
SslContextFactory
sslContextFactory
=
new
SslContextFactory
.
Client
();
HttpClient
httpClient
=
new
HttpClient
(
sslContextFactory
);
HttpClient
httpClient
=
new
HttpClient
(
sslContextFactory
);
return
new
JettyClientHttpConnector
(
httpClient
,
jettyResourceFactory
);
return
new
JettyClientHttpConnector
(
httpClient
,
jettyResourceFactory
);
...
@@ -86,4 +89,17 @@ class ClientHttpConnectorConfiguration {
...
@@ -86,4 +89,17 @@ class ClientHttpConnectorConfiguration {
}
}
@Configuration
(
proxyBeanMethods
=
false
)
@ConditionalOnClass
({
HttpAsyncClients
.
class
,
AsyncRequestProducer
.
class
})
@ConditionalOnMissingBean
(
ClientHttpConnector
.
class
)
static
class
HttpClient5
{
@Bean
@Lazy
HttpComponentsClientHttpConnector
httpComponentsClientHttpConnector
()
{
return
new
HttpComponentsClientHttpConnector
();
}
}
}
}
spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/function/client/ClientHttpConnectorAutoConfigurationTests.java
View file @
ba258390
/*
/*
* Copyright 2012-202
0
the original author or authors.
* Copyright 2012-202
1
the original author or authors.
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* you may not use this file except in compliance with the License.
...
@@ -16,10 +16,13 @@
...
@@ -16,10 +16,13 @@
package
org
.
springframework
.
boot
.
autoconfigure
.
web
.
reactive
.
function
.
client
;
package
org
.
springframework
.
boot
.
autoconfigure
.
web
.
reactive
.
function
.
client
;
import
org.eclipse.jetty.reactive.client.ReactiveRequest
;
import
org.junit.jupiter.api.Test
;
import
org.junit.jupiter.api.Test
;
import
reactor.netty.http.client.HttpClient
;
import
org.springframework.beans.factory.config.BeanDefinition
;
import
org.springframework.beans.factory.config.BeanDefinition
;
import
org.springframework.boot.autoconfigure.AutoConfigurations
;
import
org.springframework.boot.autoconfigure.AutoConfigurations
;
import
org.springframework.boot.test.context.FilteredClassLoader
;
import
org.springframework.boot.test.context.runner.ApplicationContextRunner
;
import
org.springframework.boot.test.context.runner.ApplicationContextRunner
;
import
org.springframework.boot.web.reactive.function.client.WebClientCustomizer
;
import
org.springframework.boot.web.reactive.function.client.WebClientCustomizer
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Bean
;
...
@@ -46,7 +49,7 @@ class ClientHttpConnectorAutoConfigurationTests {
...
@@ -46,7 +49,7 @@ class ClientHttpConnectorAutoConfigurationTests {
.
withConfiguration
(
AutoConfigurations
.
of
(
ClientHttpConnectorAutoConfiguration
.
class
));
.
withConfiguration
(
AutoConfigurations
.
of
(
ClientHttpConnectorAutoConfiguration
.
class
));
@Test
@Test
void
shouldCreateResourcesLazily
()
{
void
whenReactorIsAvailableThenReactorBeansAreDefined
()
{
this
.
contextRunner
.
run
((
context
)
->
{
this
.
contextRunner
.
run
((
context
)
->
{
BeanDefinition
customizerDefinition
=
context
.
getBeanFactory
()
BeanDefinition
customizerDefinition
=
context
.
getBeanFactory
()
.
getBeanDefinition
(
"clientConnectorCustomizer"
);
.
getBeanDefinition
(
"clientConnectorCustomizer"
);
...
@@ -54,9 +57,35 @@ class ClientHttpConnectorAutoConfigurationTests {
...
@@ -54,9 +57,35 @@ class ClientHttpConnectorAutoConfigurationTests {
BeanDefinition
connectorDefinition
=
context
.
getBeanFactory
()
BeanDefinition
connectorDefinition
=
context
.
getBeanFactory
()
.
getBeanDefinition
(
"reactorClientHttpConnector"
);
.
getBeanDefinition
(
"reactorClientHttpConnector"
);
assertThat
(
connectorDefinition
.
isLazyInit
()).
isTrue
();
assertThat
(
connectorDefinition
.
isLazyInit
()).
isTrue
();
assertThat
(
context
).
hasBean
(
"reactorClientResourceFactory"
);
});
});
}
}
@Test
void
whenReactorIsUnavailableThenJettyBeansAreDefined
()
{
this
.
contextRunner
.
withClassLoader
(
new
FilteredClassLoader
(
HttpClient
.
class
)).
run
((
context
)
->
{
BeanDefinition
customizerDefinition
=
context
.
getBeanFactory
()
.
getBeanDefinition
(
"clientConnectorCustomizer"
);
assertThat
(
customizerDefinition
.
isLazyInit
()).
isTrue
();
BeanDefinition
connectorDefinition
=
context
.
getBeanFactory
().
getBeanDefinition
(
"jettyClientHttpConnector"
);
assertThat
(
connectorDefinition
.
isLazyInit
()).
isTrue
();
assertThat
(
context
).
hasBean
(
"jettyClientResourceFactory"
);
});
}
@Test
void
whenReactorAndJettyAreUnavailableThenHttpClientBeansAreDefined
()
{
this
.
contextRunner
.
withClassLoader
(
new
FilteredClassLoader
(
HttpClient
.
class
,
ReactiveRequest
.
class
))
.
run
((
context
)
->
{
BeanDefinition
customizerDefinition
=
context
.
getBeanFactory
()
.
getBeanDefinition
(
"clientConnectorCustomizer"
);
assertThat
(
customizerDefinition
.
isLazyInit
()).
isTrue
();
BeanDefinition
connectorDefinition
=
context
.
getBeanFactory
()
.
getBeanDefinition
(
"httpComponentsClientHttpConnector"
);
assertThat
(
connectorDefinition
.
isLazyInit
()).
isTrue
();
});
}
@Test
@Test
void
shouldCreateHttpClientBeans
()
{
void
shouldCreateHttpClientBeans
()
{
this
.
contextRunner
.
run
((
context
)
->
{
this
.
contextRunner
.
run
((
context
)
->
{
...
...
spring-boot-project/spring-boot-dependencies/build.gradle
View file @
ba258390
...
@@ -483,14 +483,33 @@ bom {
...
@@ -483,14 +483,33 @@ bom {
]
]
}
}
}
}
library
(
"HttpClient5"
,
"5.0.3"
)
{
group
(
"org.apache.httpcomponents.client5"
)
{
modules
=
[
"httpclient5"
,
"httpclient5-cache"
,
"httpclient5-fluent"
,
"httpclient5-win"
,
]
}
}
library
(
"HttpCore"
,
"4.4.14"
)
{
library
(
"HttpCore"
,
"4.4.14"
)
{
group
(
"org.apache.httpcomponents"
)
{
group
(
"org.apache.httpcomponents
.core5
"
)
{
modules
=
[
modules
=
[
"httpcore"
,
"httpcore"
,
"httpcore-nio"
"httpcore-nio"
]
]
}
}
}
}
library
(
"HttpCore5"
,
"5.1"
)
{
group
(
"org.apache.httpcomponents"
)
{
modules
=
[
"httpcore5"
,
"httpcore5-h2"
,
"httpcore5-reactive"
]
}
}
library
(
"Infinispan"
,
"12.0.2.Final"
)
{
library
(
"Infinispan"
,
"12.0.2.Final"
)
{
group
(
"org.infinispan"
)
{
group
(
"org.infinispan"
)
{
imports
=
[
imports
=
[
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment