001package io.freefair.spring.okhttp; 002 003import okhttp3.OkHttpClient; 004import org.springframework.beans.factory.ObjectProvider; 005import org.springframework.boot.autoconfigure.AutoConfigureAfter; 006import org.springframework.boot.autoconfigure.AutoConfigureBefore; 007import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 008import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 009import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; 010import org.springframework.boot.autoconfigure.condition.NoneNestedConditions; 011import org.springframework.boot.autoconfigure.http.HttpMessageConverters; 012import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration; 013import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration; 014import org.springframework.boot.web.client.RestTemplateBuilder; 015import org.springframework.boot.web.client.RestTemplateCustomizer; 016import org.springframework.boot.web.client.RestTemplateRequestCustomizer; 017import org.springframework.context.annotation.Bean; 018import org.springframework.context.annotation.Conditional; 019import org.springframework.context.annotation.Configuration; 020import org.springframework.context.annotation.Lazy; 021import org.springframework.http.client.OkHttp3ClientHttpRequestFactory; 022import org.springframework.web.client.RestTemplate; 023 024import java.util.Collection; 025import java.util.List; 026import java.util.function.BiFunction; 027import java.util.stream.Collectors; 028 029/** 030 * @author Lars Grefer 031 * @see RestTemplateAutoConfiguration 032 */ 033@Configuration(proxyBeanMethods = false) 034@ConditionalOnClass({RestTemplateCustomizer.class, RestTemplate.class}) 035@AutoConfigureBefore(RestTemplateAutoConfiguration.class) 036@AutoConfigureAfter(HttpMessageConvertersAutoConfiguration.class) 037@Conditional(OkHttpRestTemplateAutoConfiguration.NotReactiveWebApplicationCondition.class) 038public class OkHttpRestTemplateAutoConfiguration { 039 040 @Bean 041 @Lazy 042 @ConditionalOnMissingBean 043 public RestTemplateBuilder restTemplateBuilder(ObjectProvider<HttpMessageConverters> messageConverters, 044 ObjectProvider<RestTemplateCustomizer> restTemplateCustomizers, 045 ObjectProvider<RestTemplateRequestCustomizer<?>> restTemplateRequestCustomizers, 046 OkHttpClient okHttpClient) { 047 RestTemplateBuilder builder = new RestTemplateBuilder(); 048 HttpMessageConverters converters = messageConverters.getIfUnique(); 049 if (converters != null) { 050 builder = builder.messageConverters(converters.getConverters()); 051 } 052 builder = addCustomizers(builder, restTemplateCustomizers, RestTemplateBuilder::customizers); 053 builder = addCustomizers(builder, restTemplateRequestCustomizers, RestTemplateBuilder::requestCustomizers); 054 055 builder = builder.requestFactory(() -> new OkHttp3ClientHttpRequestFactory(okHttpClient)); 056 057 return builder; 058 } 059 060 private <T> RestTemplateBuilder addCustomizers(RestTemplateBuilder builder, ObjectProvider<T> objectProvider, 061 BiFunction<RestTemplateBuilder, Collection<T>, RestTemplateBuilder> method) { 062 List<T> customizers = objectProvider.orderedStream().collect(Collectors.toList()); 063 if (!customizers.isEmpty()) { 064 return method.apply(builder, customizers); 065 } 066 return builder; 067 } 068 069 static class NotReactiveWebApplicationCondition extends NoneNestedConditions { 070 071 NotReactiveWebApplicationCondition() { 072 super(ConfigurationPhase.PARSE_CONFIGURATION); 073 } 074 075 @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) 076 private static class ReactiveWebApplication { 077 078 } 079 080 } 081 082}