/**
* 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);
}
};
}
}
}