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.AutoConfiguration; 007import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 008import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 009import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 010import org.springframework.boot.context.properties.EnableConfigurationProperties; 011import org.springframework.context.annotation.Bean; 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@AutoConfiguration 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 ObjectProvider<EventListener> eventListener 050 ) { 051 OkHttpClient.Builder builder = new OkHttpClient.Builder(); 052 053 cache.ifUnique(builder::cache); 054 055 eventListener.ifUnique(builder::eventListener); 056 057 builder.connectTimeout(okHttpProperties.getConnectTimeout().toMillis(), TimeUnit.MILLISECONDS); 058 builder.readTimeout(okHttpProperties.getReadTimeout().toMillis(), TimeUnit.MILLISECONDS); 059 builder.writeTimeout(okHttpProperties.getWriteTimeout().toMillis(), TimeUnit.MILLISECONDS); 060 builder.pingInterval(okHttpProperties.getPingInterval().toMillis(), TimeUnit.MILLISECONDS); 061 062 cookieJar.ifUnique(builder::cookieJar); 063 064 dns.ifUnique(builder::dns); 065 066 builder.connectionPool(connectionPool); 067 068 builder.followRedirects(okHttpProperties.isFollowRedirects()); 069 builder.followSslRedirects(okHttpProperties.isFollowSslRedirects()); 070 builder.retryOnConnectionFailure(okHttpProperties.isRetryOnConnectionFailure()); 071 072 applicationInterceptors.forEach(builder::addInterceptor); 073 074 networkInterceptors.forEach(builder::addNetworkInterceptor); 075 076 configurers.forEach(configurer -> configurer.configure(builder)); 077 078 return builder.build(); 079 } 080 081 @Bean 082 @ConditionalOnMissingBean 083 public ConnectionPool okHttp3ConnectionPool() { 084 int maxIdleConnections = okHttpProperties.getConnectionPool().getMaxIdleConnections(); 085 Duration keepAliveDuration = okHttpProperties.getConnectionPool().getKeepAliveDuration(); 086 return new ConnectionPool(maxIdleConnections, keepAliveDuration.toNanos(), TimeUnit.NANOSECONDS); 087 } 088 089 @Bean 090 @ConditionalOnMissingBean 091 @ConditionalOnProperty(value = "okhttp.cache.enabled", havingValue = "true", matchIfMissing = true) 092 public Cache okHttp3Cache() throws IOException { 093 File directory = okHttpProperties.getCache().getDirectory(); 094 if (directory == null) { 095 directory = Files.createTempDirectory("okhttp-cache").toFile(); 096 } 097 return new Cache(directory, okHttpProperties.getCache().getMaxSize().toBytes()); 098 } 099}