专栏首页码匠的流水账聊聊spring cloud netflix ribbon的eager load
原创

聊聊spring cloud netflix ribbon的eager load

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

RibbonAutoConfiguration

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

@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

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

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

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

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

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

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 聊聊spring cloud netflix ribbon的eager load

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

    codecraft
  • 聊聊spring cloud的consulRetryInterceptor

    本文主要研究一下spring cloud的consulRetryInterceptor

    codecraft
  • 聊聊spring for kafka的AckMode

    本文主要讲述一下spring for kafka的consumer在spring.kafka.consumer.enable-auto-commit是false...

    codecraft
  • 聊聊spring cloud netflix ribbon的eager load

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

    codecraft
  • 七夕最污代码,单身慎入

    2.找不到对象说爱(Fatal error: Call to a member function on a non-object), 他怎么才能说出爱?

    后端技术探索
  • react的事件处理为什么要bind this 改变this的指向?

    这句话大概意思就是,你要小心jax回调函数里面的this,class方法默认是不会绑定它的

    Tz一号
  • PHP设计模式——抽象方法

    Dragon公司的业务受到轰炸,而CEO希望特许所有海外分支机构的专营权。他首先要注意的问题是如何确保产品质量。他们不希望特许经营者削减成本和使用低质量的组件。...

    Lemon黄
  • springboot之mvc原理(二)-能力支持

    前边一篇文章《springboot之mvc原理(一)-请求处理》我们详细分析了springboot应用接收http请求的处理过程,那么进一步的思考一下,...

    叔牙
  • 面向对象版tab 栏切换案例

    梨涡浅笑
  • React 深入系列5:事件处理

    iKcamp

扫码关注云+社区

领取腾讯云代金券