/**
* Auto configuration for Ribbon (client side load balancing).
*
* @author Spencer Gibb
* @author Dave Syer
* @author Will Tran
*/
@Configuration
@ConditionalOnClass
(RestTemplate.
class
)
//條件 : RestTemplate必須在工程的類路徑下
@ConditionalOnBean
(LoadBalancerClient.
class
)
//條件: Spring 容器中必須包含LoadBalancerClient的實現,即RibbonLoadBalancerClient
@EnableConfigurationProperties
(LoadBalancerRetryProperties.
class
)
//啟動重試功能,可以spring.cloud.loadbalancer.retry=false,取消重試,默認參數為true
public
class
LoadBalancerAutoConfiguration {
@LoadBalanced
@Autowired
(required =
false
)
private
List<RestTemplate> restTemplates = Collections.emptyList();
//維護一個RestTemplate列表,通過LoadBalanced來注解。
@Bean
public
SmartInitializingSingleton loadBalancedRestTemplateInitializer(
//加載初始話自定義的restTeplate,實質是初始化InterceptingHttpAccessor具體調用
final
List<RestTemplateCustomizer> customizers) {
return
new
SmartInitializingSingleton() {
@Override
public
void
afterSingletonsInstantiated() {
for
(RestTemplate restTemplate : LoadBalancerAutoConfiguration.
this
.restTemplates) {
for
(RestTemplateCustomizer customizer : customizers) {
customizer.customize(restTemplate);
}
}
}
};
}
@Autowired
(required =
false
)
private
List<LoadBalancerRequestTransformer> transformers = Collections.emptyList();
@Bean
@ConditionalOnMissingBean
public
LoadBalancerRequestFactory loadBalancerRequestFactory(
LoadBalancerClient loadBalancerClient) {
return
new
LoadBalancerRequestFactory(loadBalancerClient, transformers);
}
@Configuration
@ConditionalOnMissingClass
(
"org.springframework.retry.support.RetryTemplate"
)
static
class
LoadBalancerInterceptorConfig {
@Bean
public
LoadBalancerInterceptor ribbonInterceptor(
LoadBalancerClient loadBalancerClient,
LoadBalancerRequestFactory requestFactory) {
return
new
LoadBalancerInterceptor(loadBalancerClient, requestFactory);
}
@Bean
@ConditionalOnMissingBean
public
RestTemplateCustomizer restTemplateCustomizer(
final
LoadBalancerInterceptor loadBalancerInterceptor) {
return
new
RestTemplateCustomizer() {
@Override
public
void
customize(RestTemplate restTemplate) {
List<ClientHttpRequestInterceptor> list =
new
ArrayList<>(
restTemplate.getInterceptors());
list.add(loadBalancerInterceptor);
restTemplate.setInterceptors(list);
}
};
}
}
@Configuration
@ConditionalOnClass
(RetryTemplate.
class
)
static
class
RetryAutoConfiguration {
@Bean
public
RetryTemplate retryTemplate() {
RetryTemplate template =
new
RetryTemplate();
template.setThrowLastExceptionOnExhausted(
true
);
return
template;
}
@Bean
@ConditionalOnMissingBean
public
LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory() {
return
new
LoadBalancedRetryPolicyFactory.NeverRetryFactory();
}
@Bean
public
RetryLoadBalancerInterceptor ribbonInterceptor(
LoadBalancerClient loadBalancerClient, LoadBalancerRetryProperties properties,
LoadBalancedRetryPolicyFactory lbRetryPolicyFactory,
LoadBalancerRequestFactory requestFactory) {
return
new
RetryLoadBalancerInterceptor(loadBalancerClient, retryTemplate(), properties,
lbRetryPolicyFactory, requestFactory);
}
@Bean
@ConditionalOnMissingBean
public
RestTemplateCustomizer restTemplateCustomizer(
//自定義RestTemplate ,實質是初始化InterceptingHttpAccessor
final
RetryLoadBalancerInterceptor loadBalancerInterceptor) {
return
new
RestTemplateCustomizer() {
@Override
public
void
customize(RestTemplate restTemplate) {
List<ClientHttpRequestInterceptor> list =
new
ArrayList<>(
restTemplate.getInterceptors());
list.add(loadBalancerInterceptor);
restTemplate.setInterceptors(list);
}
};
}
}
}