diff --git a/docs/src/main/asciidoc/spring-cloud-commons.adoc b/docs/src/main/asciidoc/spring-cloud-commons.adoc
index d0f2f07e..eb7c3352 100644
--- a/docs/src/main/asciidoc/spring-cloud-commons.adoc
+++ b/docs/src/main/asciidoc/spring-cloud-commons.adoc
@@ -612,6 +612,8 @@ if the OK HTTP jar is on the classpath. In addition, Spring Cloud Commons provi
the connection managers used by both clients, `ApacheHttpClientConnectionManagerFactory` for the Apache
HTTP client and `OkHttpClientConnectionPoolFactory` for the OK HTTP client. You can provide
your own implementation of these beans if you would like to customize how the HTTP clients are created
-in downstream projects. You can also disable the creation of these beans by setting
+in downstream projects. In addition, if you provide a bean of type `HttpClientBuilder` and/or `OkHttpClient.Builder`,
+the default factories will use these builders as the basis for the builders returned to downstream projects.
+You can also disable the creation of these beans by setting
`spring.cloud.httpclientfactories.apache.enabled` or `spring.cloud.httpclientfactories.ok.enabled` to
`false`.
diff --git a/spring-cloud-commons/pom.xml b/spring-cloud-commons/pom.xml
index 34837d1d..cf52eb20 100644
--- a/spring-cloud-commons/pom.xml
+++ b/spring-cloud-commons/pom.xml
@@ -66,7 +66,7 @@
3.6.0
- 4.5.1
+ 4.5.4
diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/httpclient/DefaultApacheHttpClientFactory.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/httpclient/DefaultApacheHttpClientFactory.java
index da90c05e..1b54aa04 100644
--- a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/httpclient/DefaultApacheHttpClientFactory.java
+++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/httpclient/DefaultApacheHttpClientFactory.java
@@ -8,13 +8,19 @@ import org.apache.http.impl.client.HttpClientBuilder;
*/
public class DefaultApacheHttpClientFactory implements ApacheHttpClientFactory {
+ private HttpClientBuilder builder;
+
+ public DefaultApacheHttpClientFactory(HttpClientBuilder builder) {
+ this.builder = builder;
+ }
+
/**
* A default {@link HttpClientBuilder}. The {@link HttpClientBuilder} returned will
* have content compression disabled, cookie management disabled, and use system properties.
*/
@Override
public HttpClientBuilder createBuilder() {
- return HttpClientBuilder.create().disableContentCompression()
+ return this.builder.disableContentCompression()
.disableCookieManagement().useSystemProperties();
}
}
diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/httpclient/DefaultOkHttpClientFactory.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/httpclient/DefaultOkHttpClientFactory.java
index 4c5fd074..a30234e2 100644
--- a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/httpclient/DefaultOkHttpClientFactory.java
+++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/httpclient/DefaultOkHttpClientFactory.java
@@ -19,9 +19,14 @@ public class DefaultOkHttpClientFactory implements OkHttpClientFactory {
private static final Log LOG = LogFactory.getLog(DefaultOkHttpClientFactory.class);
+ private OkHttpClient.Builder builder;
+
+ public DefaultOkHttpClientFactory(OkHttpClient.Builder builder) {
+ this.builder = builder;
+ }
+
@Override
public OkHttpClient.Builder createBuilder(boolean disableSslValidation) {
- OkHttpClient.Builder builder = new OkHttpClient.Builder();
if (disableSslValidation) {
try {
X509TrustManager disabledTrustManager = new DisableValidationTrustManager();
diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/httpclient/HttpClientConfiguration.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/httpclient/HttpClientConfiguration.java
index df3de178..1ab488fb 100644
--- a/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/httpclient/HttpClientConfiguration.java
+++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/commons/httpclient/HttpClientConfiguration.java
@@ -2,6 +2,7 @@ package org.springframework.cloud.commons.httpclient;
import okhttp3.OkHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -26,8 +27,14 @@ public class HttpClientConfiguration {
@Bean
@ConditionalOnMissingBean
- public ApacheHttpClientFactory apacheHttpClientFactory() {
- return new DefaultApacheHttpClientFactory();
+ public HttpClientBuilder apacheHttpClientBuilder() {
+ return HttpClientBuilder.create();
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public ApacheHttpClientFactory apacheHttpClientFactory(HttpClientBuilder builder) {
+ return new DefaultApacheHttpClientFactory(builder);
}
}
@@ -44,8 +51,14 @@ public class HttpClientConfiguration {
@Bean
@ConditionalOnMissingBean
- public OkHttpClientFactory okHttpClientFactory() {
- return new DefaultOkHttpClientFactory();
+ public OkHttpClient.Builder okHttpClientBuilder() {
+ return new OkHttpClient.Builder();
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public OkHttpClientFactory okHttpClientFactory(OkHttpClient.Builder builder) {
+ return new DefaultOkHttpClientFactory(builder);
}
}
}
diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/httpclient/CustomHttpClientBuilderConfigurationTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/httpclient/CustomHttpClientBuilderConfigurationTests.java
new file mode 100644
index 00000000..a55c6dc0
--- /dev/null
+++ b/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/httpclient/CustomHttpClientBuilderConfigurationTests.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2013-2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.cloud.commons.httpclient;
+
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author Ryan Baxter
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = CustomHttpClientBuilderApplication.class)
+public class CustomHttpClientBuilderConfigurationTests {
+
+ @Autowired
+ ApacheHttpClientFactory apacheHttpClientFactory;
+
+ @Test
+ public void testCustomBuilder() {
+ HttpClientBuilder builder = apacheHttpClientFactory.createBuilder();
+ assertTrue(CustomHttpClientBuilderApplication.MyHttpClientBuilder.class.isInstance(builder));
+ }
+}
+
+@Configuration
+@EnableAutoConfiguration
+class CustomHttpClientBuilderApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(MyApplication.class, args);
+ }
+
+ @Configuration
+ @AutoConfigureBefore(value = HttpClientConfiguration.class)
+ static class MyConfig {
+
+ @Bean
+ public MyHttpClientBuilder builder() {
+ return new MyHttpClientBuilder();
+ }
+
+ }
+
+ static class MyHttpClientBuilder extends HttpClientBuilder {
+ }
+}
diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/httpclient/CustomOkHttpClientBuilderConfigurationTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/httpclient/CustomOkHttpClientBuilderConfigurationTests.java
new file mode 100644
index 00000000..ac8afa5c
--- /dev/null
+++ b/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/httpclient/CustomOkHttpClientBuilderConfigurationTests.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2013-2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.cloud.commons.httpclient;
+
+import okhttp3.OkHttpClient;
+
+import java.lang.reflect.Field;
+import java.util.concurrent.TimeUnit;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.util.ReflectionUtils;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author Ryan Baxter
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = CustomOkHttpClientBuilderApplication.class)
+public class CustomOkHttpClientBuilderConfigurationTests {
+
+ @Autowired
+ private OkHttpClientFactory okHttpClientFactory;
+
+ @Test
+ public void testCustomBuilder() {
+ OkHttpClient.Builder builder = okHttpClientFactory.createBuilder(false);
+ Integer timeout = getField(builder, "connectTimeout");
+ assertEquals(1, timeout.intValue());
+ }
+
+ protected T getField(Object target, String name) {
+ Field field = ReflectionUtils.findField(target.getClass(), name);
+ ReflectionUtils.makeAccessible(field);
+ Object value = ReflectionUtils.getField(field, target);
+ return (T) value;
+ }
+
+}
+
+@Configuration
+@EnableAutoConfiguration
+class CustomOkHttpClientBuilderApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(MyApplication.class, args);
+ }
+
+ @Configuration
+ static class MyConfig {
+
+ @Bean
+ public OkHttpClient.Builder builder() {
+ return new OkHttpClient.Builder().connectTimeout(1, TimeUnit.MILLISECONDS);
+ }
+ }
+}
diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/httpclient/DefaultApacheHttpClientFactoryTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/httpclient/DefaultApacheHttpClientFactoryTests.java
index 3a69ea72..03810b0a 100644
--- a/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/httpclient/DefaultApacheHttpClientFactoryTests.java
+++ b/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/httpclient/DefaultApacheHttpClientFactoryTests.java
@@ -22,7 +22,7 @@ public class DefaultApacheHttpClientFactoryTests {
public void createClient() throws Exception {
final RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(100)
.setConnectTimeout(200).setCookieSpec(CookieSpecs.IGNORE_COOKIES).build();
- CloseableHttpClient httpClient = new DefaultApacheHttpClientFactory().createBuilder().
+ CloseableHttpClient httpClient = new DefaultApacheHttpClientFactory(HttpClientBuilder.create()).createBuilder().
setConnectionManager(mock(HttpClientConnectionManager.class)).
setDefaultRequestConfig(requestConfig).build();
Assertions.assertThat(httpClient).isInstanceOf(Configurable.class);
diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/httpclient/DefaultOkHttpClientFactoryTest.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/httpclient/DefaultOkHttpClientFactoryTest.java
index 10c40516..b14e7f05 100644
--- a/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/httpclient/DefaultOkHttpClientFactoryTest.java
+++ b/spring-cloud-commons/src/test/java/org/springframework/cloud/commons/httpclient/DefaultOkHttpClientFactoryTest.java
@@ -18,7 +18,7 @@ import static org.junit.Assert.assertTrue;
public class DefaultOkHttpClientFactoryTest {
@Test
public void create() throws Exception {
- DefaultOkHttpClientFactory okHttpClientFactory = new DefaultOkHttpClientFactory();
+ DefaultOkHttpClientFactory okHttpClientFactory = new DefaultOkHttpClientFactory(new OkHttpClient.Builder());
DefaultOkHttpClientConnectionPoolFactory poolFactory = new DefaultOkHttpClientConnectionPoolFactory();
ConnectionPool pool = poolFactory.create(4, 5, TimeUnit.DAYS);
OkHttpClient httpClient = okHttpClientFactory.createBuilder(true).