001package io.freefair.spring.okhttp; 002 003import okhttp3.*; 004import org.springframework.beans.factory.ObjectProvider; 005import org.springframework.beans.factory.annotation.Autowired; 006import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 007import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 008import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 009import org.springframework.boot.context.properties.EnableConfigurationProperties; 010import org.springframework.context.annotation.Bean; 011import org.springframework.context.annotation.Configuration; 012 013import java.io.File; 014import java.io.IOException; 015import java.nio.file.Files; 016import java.time.Duration; 017import java.util.concurrent.TimeUnit; 018 019/** 020 * @author Lars Grefer 021 */ 022@SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection") 023@Configuration(proxyBeanMethods = false) 024@ConditionalOnClass(OkHttpClient.class) 025@EnableConfigurationProperties(OkHttpProperties.class) 026public class OkHttp3AutoConfiguration { 027 028 @Autowired 029 private OkHttpProperties okHttpProperties; 030 031 @Autowired 032 private ObjectProvider<OkHttp3Configurer> configurers; 033 034 @Autowired 035 @ApplicationInterceptor 036 private ObjectProvider<Interceptor> applicationInterceptors; 037 038 @Autowired 039 @NetworkInterceptor 040 private ObjectProvider<Interceptor> networkInterceptors; 041 042 @Bean 043 @ConditionalOnMissingBean 044 public OkHttpClient okHttp3Client( 045 ObjectProvider<Cache> cache, 046 ObjectProvider<CookieJar> cookieJar, 047 ObjectProvider<Dns> dns, 048 ConnectionPool connectionPool 049 ) { 050 OkHttpClient.Builder builder = new OkHttpClient.Builder(); 051 052 cache.ifUnique(builder::cache); 053 054 builder.connectTimeout(okHttpProperties.getConnectTimeout().toMillis(), TimeUnit.MILLISECONDS); 055 builder.readTimeout(okHttpProperties.getReadTimeout().toMillis(), TimeUnit.MILLISECONDS); 056 builder.writeTimeout(okHttpProperties.getWriteTimeout().toMillis(), TimeUnit.MILLISECONDS); 057 builder.pingInterval(okHttpProperties.getPingInterval().toMillis(), TimeUnit.MILLISECONDS); 058 059 cookieJar.ifUnique(builder::cookieJar); 060 061 dns.ifUnique(builder::dns); 062 063 builder.connectionPool(connectionPool); 064 065 builder.followRedirects(okHttpProperties.isFollowRedirects()); 066 builder.followSslRedirects(okHttpProperties.isFollowSslRedirects()); 067 builder.retryOnConnectionFailure(okHttpProperties.isRetryOnConnectionFailure()); 068 069 applicationInterceptors.forEach(builder::addInterceptor); 070 071 networkInterceptors.forEach(builder::addNetworkInterceptor); 072 073 configurers.forEach(configurer -> configurer.configure(builder)); 074 075 return builder.build(); 076 } 077 078 @Bean 079 @ConditionalOnMissingBean 080 public ConnectionPool okHttp3ConnectionPool() { 081 int maxIdleConnections = okHttpProperties.getConnectionPool().getMaxIdleConnections(); 082 Duration keepAliveDuration = okHttpProperties.getConnectionPool().getKeepAliveDuration(); 083 return new ConnectionPool(maxIdleConnections, keepAliveDuration.toNanos(), TimeUnit.NANOSECONDS); 084 } 085 086 @Bean 087 @ConditionalOnMissingBean 088 @ConditionalOnProperty(value = "okhttp.cache.enabled", havingValue = "true", matchIfMissing = true) 089 public Cache okHttp3Cache() throws IOException { 090 File directory = okHttpProperties.getCache().getDirectory(); 091 if (directory == null) { 092 directory = Files.createTempDirectory("okhttp-cache").toFile(); 093 } 094 return new Cache(directory, okHttpProperties.getCache().getMaxSize().toBytes()); 095 } 096}