前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >聊聊spring cloud netflix ribbon的eager load

聊聊spring cloud netflix ribbon的eager load

作者头像
code4it
发布2019-07-10 15:57:16
5180
发布2019-07-10 15:57:16
举报
文章被收录于专栏:码匠的流水账码匠的流水账

本文主要研究一下spring cloud netflix ribbon的eager load

RibbonAutoConfiguration

spring-cloud-netflix-ribbon-2.1.1.RELEASE-sources.jar!/org/springframework/cloud/netflix/ribbon/RibbonAutoConfiguration.java

代码语言:javascript
复制
@Configuration
@Conditional(RibbonAutoConfiguration.RibbonClassesConditions.class)
@RibbonClients
@AutoConfigureAfter(name = "org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration")
@AutoConfigureBefore({ LoadBalancerAutoConfiguration.class,
AsyncLoadBalancerAutoConfiguration.class })
@EnableConfigurationProperties({ RibbonEagerLoadProperties.class,
ServerIntrospectorProperties.class })
public class RibbonAutoConfiguration {

@Autowired(required = false)
private List<RibbonClientSpecification> configurations = new ArrayList<>();

@Autowired
private RibbonEagerLoadProperties ribbonEagerLoadProperties;

@Bean
public HasFeatures ribbonFeature() {
return HasFeatures.namedFeature("Ribbon", Ribbon.class);
}

@Bean
public SpringClientFactory springClientFactory() {
SpringClientFactory factory = new SpringClientFactory();
factory.setConfigurations(this.configurations);
return factory;
}

@Bean
@ConditionalOnMissingBean(LoadBalancerClient.class)
public LoadBalancerClient loadBalancerClient() {
return new RibbonLoadBalancerClient(springClientFactory());
}

@Bean
@ConditionalOnClass(name = "org.springframework.retry.support.RetryTemplate")
@ConditionalOnMissingBean
public LoadBalancedRetryFactory loadBalancedRetryPolicyFactory(
final SpringClientFactory clientFactory) {
return new RibbonLoadBalancedRetryFactory(clientFactory);
}

@Bean
@ConditionalOnMissingBean
public PropertiesFactory propertiesFactory() {
return new PropertiesFactory();
}

@Bean
@ConditionalOnProperty("ribbon.eager-load.enabled")
public RibbonApplicationContextInitializer ribbonApplicationContextInitializer() {
return new RibbonApplicationContextInitializer(springClientFactory(),
ribbonEagerLoadProperties.getClients());
}

@Configuration
@ConditionalOnClass(HttpRequest.class)
@ConditionalOnRibbonRestClient
protected static class RibbonClientHttpRequestFactoryConfiguration {

@Autowired
private SpringClientFactory springClientFactory;

@Bean
public RestTemplateCustomizer restTemplateCustomizer(
final RibbonClientHttpRequestFactory ribbonClientHttpRequestFactory) {
return restTemplate -> restTemplate
.setRequestFactory(ribbonClientHttpRequestFactory);
}

@Bean
public RibbonClientHttpRequestFactory ribbonClientHttpRequestFactory() {
return new RibbonClientHttpRequestFactory(this.springClientFactory);
}

}

// TODO: support for autoconfiguring restemplate to use apache http client or okhttp

@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnRibbonRestClientCondition.class)
@interface ConditionalOnRibbonRestClient {

}

private static class OnRibbonRestClientCondition extends AnyNestedCondition {

OnRibbonRestClientCondition() {
super(ConfigurationPhase.REGISTER_BEAN);
}

@Deprecated // remove in Edgware"
@ConditionalOnProperty("ribbon.http.client.enabled")
static class ZuulProperty {

}

@ConditionalOnProperty("ribbon.restclient.enabled")
static class RibbonProperty {

}

}

/**
 * {@link AllNestedConditions} that checks that either multiple classes are present.
 */
static class RibbonClassesConditions extends AllNestedConditions {

RibbonClassesConditions() {
super(ConfigurationPhase.PARSE_CONFIGURATION);
}

@ConditionalOnClass(IClient.class)
static class IClientPresent {

}

@ConditionalOnClass(RestTemplate.class)
static class RestTemplatePresent {

}

@ConditionalOnClass(AsyncRestTemplate.class)
static class AsyncRestTemplatePresent {

}

@ConditionalOnClass(Ribbon.class)
static class RibbonPresent {

}

}

}
  • RibbonAutoConfiguration启用了RibbonEagerLoadProperties、ServerIntrospectorProperties两个配置,这里主要是注册了SpringClientFactory,创建LoadBalancerClient、LoadBalancedRetryFactory、RibbonApplicationContextInitializer、RestTemplateCustomizer及RibbonClientHttpRequestFactory

RibbonApplicationContextInitializer

spring-cloud-netflix-ribbon-2.1.1.RELEASE-sources.jar!/org/springframework/cloud/netflix/ribbon/RibbonApplicationContextInitializer.java

代码语言:javascript
复制
public class RibbonApplicationContextInitializer
implements ApplicationListener<ApplicationReadyEvent> {

private final SpringClientFactory springClientFactory;

// List of Ribbon client names
private final List<String> clientNames;

public RibbonApplicationContextInitializer(SpringClientFactory springClientFactory,
List<String> clientNames) {
this.springClientFactory = springClientFactory;
this.clientNames = clientNames;
}

protected void initialize() {
if (clientNames != null) {
for (String clientName : clientNames) {
this.springClientFactory.getContext(clientName);
}
}
}

@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
initialize();
}

}
  • RibbonApplicationContextInitializer实现了ApplicationListener接口,其响应ApplicationReadyEvent事件执行initialize操作,这里主要是挨个对配置的clientNames执行springClientFactory.getContext(clientName)操作

SpringClientFactory

spring-cloud-netflix-ribbon-2.1.1.RELEASE-sources.jar!/org/springframework/cloud/netflix/ribbon/SpringClientFactory.java

代码语言:javascript
复制
public class SpringClientFactory extends NamedContextFactory<RibbonClientSpecification> {
//......

protected AnnotationConfigApplicationContext getContext(String name) {
return super.getContext(name);
}

//......
}
  • SpringClientFactory的getContext方法调用了父类NamedContextFactory的getContext

NamedContextFactory

spring-cloud-context-2.2.0.M1-sources.jar!/org/springframework/cloud/context/named/NamedContextFactory.java

代码语言:javascript
复制
public abstract class NamedContextFactory<C extends NamedContextFactory.Specification>
implements DisposableBean, ApplicationContextAware {

//......

protected AnnotationConfigApplicationContext getContext(String name) {
if (!this.contexts.containsKey(name)) {
synchronized (this.contexts) {
if (!this.contexts.containsKey(name)) {
this.contexts.put(name, createContext(name));
}
}
}
return this.contexts.get(name);
}

protected AnnotationConfigApplicationContext createContext(String name) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
if (this.configurations.containsKey(name)) {
for (Class<?> configuration : this.configurations.get(name)
.getConfiguration()) {
context.register(configuration);
}
}
for (Map.Entry<String, C> entry : this.configurations.entrySet()) {
if (entry.getKey().startsWith("default.")) {
for (Class<?> configuration : entry.getValue().getConfiguration()) {
context.register(configuration);
}
}
}
context.register(PropertyPlaceholderAutoConfiguration.class,
this.defaultConfigType);
context.getEnvironment().getPropertySources().addFirst(new MapPropertySource(
this.propertySourceName,
Collections.<String, Object>singletonMap(this.propertyName, name)));
if (this.parent != null) {
// Uses Environment from parent as well as beans
context.setParent(this.parent);
// jdk11 issue
// https://github.com/spring-cloud/spring-cloud-netflix/issues/3101
context.setClassLoader(this.parent.getClassLoader());
}
context.setDisplayName(generateDisplayName(name));
context.refresh();
return context;
}

//......
}
  • NamedContextFactory的getContext主要是返回或者创建AnnotationConfigApplicationContext

小结

  • RibbonAutoConfiguration启用了RibbonEagerLoadProperties、ServerIntrospectorProperties两个配置,这里主要是注册了SpringClientFactory,创建LoadBalancerClient、LoadBalancedRetryFactory、RibbonApplicationContextInitializer、RestTemplateCustomizer及RibbonClientHttpRequestFactory
  • RibbonApplicationContextInitializer实现了ApplicationListener接口,其响应ApplicationReadyEvent事件执行initialize操作,这里主要是挨个对配置的clientNames执行springClientFactory.getContext(clientName)操作
  • SpringClientFactory的getContext方法调用了父类NamedContextFactory的getContext;NamedContextFactory的getContext主要是返回或者创建AnnotationConfigApplicationContext

doc

  • RibbonClientConfiguration
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-07-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码匠的流水账 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • RibbonAutoConfiguration
  • RibbonApplicationContextInitializer
  • SpringClientFactory
  • NamedContextFactory
  • 小结
  • doc
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档