SpringCloud之Ribbon源码解析(三)--@LoadBalanced
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了SpringCloud之Ribbon源码解析(三)--@LoadBalanced,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4676字,纯文字阅读大概需要7分钟。
内容图文
本文着重分析下为什么加了@LoadBalanced就有了负载均衡的能力
先看现象
我们写代码都是这么写的
@SpringBootApplication @EnableEurekaClient @EnableDiscoveryClient public class ServiceRibbonApplication { public static void main(String[] args) { SpringApplication.run( ServiceRibbonApplication.class, args ); } @Bean @LoadBalanced RestTemplate restTemplate() { return new RestTemplate(); }
如果不加@LoadBalanced会怎么样呢?
@Configuration @ConditionalOnClass(RestTemplate.class) @ConditionalOnBean(LoadBalancerClient.class) @EnableConfigurationProperties(LoadBalancerRetryProperties.class) public class LoadBalancerAutoConfiguration { @LoadBalanced @Autowired(required = false) private List<RestTemplate> restTemplates = Collections.emptyList(); @Bean public SmartInitializingSingleton loadBalancedRestTemplateInitializerDeprecated( final ObjectProvider<List<RestTemplateCustomizer>> restTemplateCustomizers) { return () -> restTemplateCustomizers.ifAvailable(customizers -> { for (RestTemplate restTemplate : LoadBalancerAutoConfiguration.this.restTemplates) {//如果不加LoadBalanced那么这里restTemplates就是size=0 for (RestTemplateCustomizer customizer : customizers) { customizer.customize(restTemplate); } } }); }
所以不加@LoadBalanced注解的话,在LoadBalancerAutoConfiguration就不能自动注入restTemplates,也就导致了没法讲interceptor注入到RestTemplate中,这样RestTemplate就不会有负载均衡的能力
换句话说,如果不在启动类里面加 @LoadBalanced那么在LoadBalancerAutoConfiguration 中就没法完成@Autowired
@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @Qualifier public @interface LoadBalanced { }
@LoadBalanced是@Qualifier的父类,所以它能配合@Autowired一起使用
解析@Autowired最终会到达 DefaultListableBeanFactory
protected boolean isAutowireCandidate(String beanName, RootBeanDefinition mbd,
DependencyDescriptor descriptor, AutowireCandidateResolver resolver)
protected boolean isAutowireCandidate(String beanName, RootBeanDefinition mbd, DependencyDescriptor descriptor, AutowireCandidateResolver resolver) { String beanDefinitionName = BeanFactoryUtils.transformedBeanName(beanName); resolveBeanClass(mbd, beanDefinitionName); if (mbd.isFactoryMethodUnique) { boolean resolve; synchronized (mbd.constructorArgumentLock) { resolve = (mbd.resolvedConstructorOrFactoryMethod == null); } if (resolve) { new ConstructorResolver(this).resolveFactoryMethodIfPossible(mbd); } } return resolver.isAutowireCandidate( new BeanDefinitionHolder(mbd, beanName, getAliases(beanDefinitionName)), descriptor); }
说下上面的参数
1 beanName是要判断是否应该注入的beanName,比如restTemplate
2 DependencyDescriptor是指 描述成员变量restTemplates 的注解信息的比如它有@LoadBalanced
public class LoadBalancerAutoConfiguration { @LoadBalanced @Autowired(required = false) private List<RestTemplate> restTemplates = Collections.emptyList();
QualifierAnnotationAutowireCandidateResolver
public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) { boolean match = super.isAutowireCandidate(bdHolder, descriptor); if (match) { match = checkQualifiers(bdHolder, descriptor.getAnnotations()); if (match) { MethodParameter methodParam = descriptor.getMethodParameter(); if (methodParam != null) { Method method = methodParam.getMethod(); if (method == null || void.class == method.getReturnType()) { match = checkQualifiers(bdHolder, methodParam.getMethodAnnotations()); } } } } return match; }
protected boolean checkQualifiers(BeanDefinitionHolder bdHolder, Annotation[] annotationsToSearch) { if (ObjectUtils.isEmpty(annotationsToSearch)) { return true; } SimpleTypeConverter typeConverter = new SimpleTypeConverter(); for (Annotation annotation : annotationsToSearch) { Class<? extends Annotation> type = annotation.annotationType(); boolean checkMeta = true; boolean fallbackToMeta = false; if (isQualifier(type)) { if (!checkQualifier(bdHolder, annotation, typeConverter)) { fallbackToMeta = true; } else { checkMeta = false; } } if (checkMeta) { boolean foundMeta = false; for (Annotation metaAnn : type.getAnnotations()) { Class<? extends Annotation> metaType = metaAnn.annotationType(); if (isQualifier(metaType)) { foundMeta = true; // Only accept fallback match if @Qualifier annotation has a value... // Otherwise it is just a marker for a custom qualifier annotation. if ((fallbackToMeta && StringUtils.isEmpty(AnnotationUtils.getValue(metaAnn))) || !checkQualifier(bdHolder, metaAnn, typeConverter)) { return false; } } } if (fallbackToMeta && !foundMeta) { return false; } } } return true; }
就是判断DependencyDescriptor中有的注解,候选beanDefinition是否也有,如果没有那就不应该选择它作为@Autowired的候选了
所以说知道当我们给RestTemplate加上@LoadBalanced注解它才有负载均衡的能力
内容总结
以上是互联网集市为您收集整理的SpringCloud之Ribbon源码解析(三)--@LoadBalanced全部内容,希望文章能够帮你解决SpringCloud之Ribbon源码解析(三)--@LoadBalanced所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。