莆田网站建设网,大型门户网站核心技术,网站搭建的费用,域名服务商是什么意思Ribbon服务实现不同服务#xff0c;不同配置是通过RibbonClient和RibbonClients两个注解来实现的。RibbonClient注册的某个Client配置类。RibbonClients注册的全局默认配置类。
Feign实现不同服务#xff0c;不同配置#xff0c;是根据FeignClient来获取自定义的配置。
示…Ribbon服务实现不同服务不同配置是通过RibbonClient和RibbonClients两个注解来实现的。RibbonClient注册的某个Client配置类。RibbonClients注册的全局默认配置类。
Feign实现不同服务不同配置是根据FeignClient来获取自定义的配置。
示例
定义Ribbon配置类
public class AppRibbonConfig {Beanpublic IPing iping() {return new DummyPing();}
}启动类上添加注解
RibbonClient(name app-provider, configuration AppRibbonConfig.class)
源码解析
RibbonClient和RibbonClients
这两个注解的功能都是引入RibbonClientConfigurationRegistrar该类主要是生成RibbonClientSpecification的BeanDefinition。
RibbonAutoConfiguration
该类会获取到所有的RibbonClientSpecification设置到SpringClientFactory的map集合中。
public class RibbonAutoConfiguration {Autowired(required false)private ListRibbonClientSpecification configurations new ArrayList();Autowiredprivate RibbonEagerLoadProperties ribbonEagerLoadProperties;public RibbonAutoConfiguration() {}Beanpublic HasFeatures ribbonFeature() {return HasFeatures.namedFeature(Ribbon, Ribbon.class);}Beanpublic SpringClientFactory springClientFactory() {SpringClientFactory factory new SpringClientFactory();factory.setConfigurations(this.configurations);return factory;}
}系统中默认的配置有RibbonAutoConfiguration和RibbonEurekaAutoConfigurationRibbonEurekaAutoConfiguration类上的注解上含有配置类EurekaRibbonClientConfiguration。
Configuration
EnableConfigurationProperties
ConditionalOnRibbonAndEurekaEnabled
AutoConfigureAfter({RibbonAutoConfiguration.class})
RibbonClients(defaultConfiguration {EurekaRibbonClientConfiguration.class}
)
public class RibbonEurekaAutoConfiguration {public RibbonEurekaAutoConfiguration() {}
}EnableFeignClients
该类会注册FeignClientSpecification。FeignClientsRegistrar#registerBeanDefinitions会加载默认配置和对应的FeignClient服务名的配置。 public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {this.registerDefaultConfiguration(metadata, registry);this.registerFeignClients(metadata, registry);}private void registerDefaultConfiguration(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {MapString, Object defaultAttrs metadata.getAnnotationAttributes(EnableFeignClients.class.getName(), true);if (defaultAttrs ! null defaultAttrs.containsKey(defaultConfiguration)) {String name;if (metadata.hasEnclosingClass()) {name default. metadata.getEnclosingClassName();} else {name default. metadata.getClassName();}this.registerClientConfiguration(registry, name, defaultAttrs.get(defaultConfiguration));}}private void registerClientConfiguration(BeanDefinitionRegistry registry, Object name, Object configuration) {BeanDefinitionBuilder builder BeanDefinitionBuilder.genericBeanDefinition(FeignClientSpecification.class);builder.addConstructorArgValue(name);builder.addConstructorArgValue(configuration);registry.registerBeanDefinition(name . FeignClientSpecification.class.getSimpleName(), builder.getBeanDefinition());}FeignAutoConfiguration
FeignAutoConfiguration会获取到FeignClientSpecification
Configuration
ConditionalOnClass({Feign.class})
EnableConfigurationProperties({FeignClientProperties.class, FeignHttpClientProperties.class})
public class FeignAutoConfiguration {Autowired(required false)private ListFeignClientSpecification configurations new ArrayList();public FeignAutoConfiguration() {}Beanpublic HasFeatures feignFeature() {return HasFeatures.namedFeature(Feign, Feign.class);}Beanpublic FeignContext feignContext() {FeignContext context new FeignContext();context.setConfigurations(this.configurations);return context;}FeignClientFactoryBean
系统启动的时候会加载FeignClientFactoryBean会执行FeignClientFactoryBean#getObject获取到context对象从而获取相应的组件。 protected Builder feign(FeignContext context) {FeignLoggerFactory loggerFactory (FeignLoggerFactory)this.get(context, FeignLoggerFactory.class);Logger logger loggerFactory.create(this.type);Builder builder ((Builder)this.get(context, Builder.class)).logger(logger).encoder((Encoder)this.get(context, Encoder.class)).decoder((Decoder)this.get(context, Decoder.class)).contract((Contract)this.get(context, Contract.class));this.configureFeign(context, builder);return builder;}protected T T get(FeignContext context, ClassT type) {T instance context.getInstance(this.contextId, type);if (instance null) {throw new IllegalStateException(No bean found of type type for this.contextId);} else {return instance;}}第一次访问服务
Ribbon是懒加载的NamedContextFactory#getContext第一次访问是没有context对象的所以会进行创建。 protected AnnotationConfigApplicationContext getContext(String name) {if (!this.contexts.containsKey(name)) {synchronized(this.contexts) {if (!this.contexts.containsKey(name)) {this.contexts.put(name, this.createContext(name));}}}return (AnnotationConfigApplicationContext)this.contexts.get(name);}NamedContextFactory#createContext根据服务配置生成对应的AnnotationConfigApplicationContext protected AnnotationConfigApplicationContext createContext(String name) {AnnotationConfigApplicationContext context new AnnotationConfigApplicationContext();if (this.configurations.containsKey(name)) {Class[] var3 ((NamedContextFactory.Specification)this.configurations.get(name)).getConfiguration();int var4 var3.length;for(int var5 0; var5 var4; var5) {Class? configuration var3[var5];context.register(new Class[]{configuration});}}Iterator var9 this.configurations.entrySet().iterator();while(true) {Entry entry;do {if (!var9.hasNext()) {context.register(new Class[]{PropertyPlaceholderAutoConfiguration.class, this.defaultConfigType});context.getEnvironment().getPropertySources().addFirst(new MapPropertySource(this.propertySourceName, Collections.singletonMap(this.propertyName, name)));if (this.parent ! null) {context.setParent(this.parent);context.setClassLoader(this.parent.getClassLoader());}context.setDisplayName(this.generateDisplayName(name));context.refresh();return context;}entry (Entry)var9.next();} while(!((String)entry.getKey()).startsWith(default.));Class[] var11 ((NamedContextFactory.Specification)entry.getValue()).getConfiguration();int var12 var11.length;for(int var7 0; var7 var12; var7) {Class? configuration var11[var7];context.register(new Class[]{configuration});}}}Ribbon提前加载
ribbon:eager-load:clients: app-providerenabled: true在RibbonAutoConfiguration中会根据配置判断是否生成对象ribbonApplicationContextInitializer
Bean
ConditionalOnProperty({ribbon.eager-load.enabled})
public RibbonApplicationContextInitializer ribbonApplicationContextInitializer() {return new RibbonApplicationContextInitializer(this.springClientFactory(), this.ribbonEagerLoadProperties.getClients());
}RibbonApplicationContextInitializer#initialize该类主要是根据配置的clients数据对相应的服务进行加载
protected void initialize() {if (this.clientNames ! null) {Iterator var1 this.clientNames.iterator();while(var1.hasNext()) {String clientName (String)var1.next();this.springClientFactory.getContext(clientName);}}
}