美文网首页
@LoadBalanced注解

@LoadBalanced注解

作者: 念䋛 | 来源:发表于2022-08-15 20:23 被阅读0次

@LoadBalanced注解在生产环境使用的不太多,主要是springcloud项目,访问下游服务的时候,用服务名称访问,并使用负载策略,但是实际生产的时候我们一般使用feign访问下游服务
@LoadBalanced的使用,RestTemplate用LoadBalanced修饰之后,就可以通过服务名称访问服务,并使用负载均衡策略,默认是轮询策略

    @Bean
    @LoadBalanced  
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

点开@LoadBalanced 注解发现


image.png

其实就是Qualifier注解,那何为Qualifier呢,是spring的注解

@Component
public class QualifierTestService {
    @Autowired
    @Qualifier
    List<TestQualifier> testQualifierList;
    @PostConstruct
    public void test() {
        System.out.println ("QualifierTestService---");
        for (TestQualifier testQualifier : testQualifierList) {
            System.out.println (testQualifier.getName ());
        }
    }
}
@Component
public class QualifierTestService1 {
    @Autowired
    List<TestQualifier> testQualifierList;
    @PostConstruct
    public void test() {
        System.out.println ("QualifierTestService1---");
        for (TestQualifier testQualifier : testQualifierList) {
            System.out.println (testQualifier.getName ());
        }
    }
}
@Data
public class TestQualifier {
    private String name;
    public void hello() {
    }
}
@Configuration
public class TestQualifierAutoConfig {
    @Bean
    @Qualifier
    public TestQualifier getTestQualifier1(){
        TestQualifier testQualifier = new TestQualifier ();
        testQualifier.setName ("TestQualifier1");
        return testQualifier;
    }
    @Bean
    public TestQualifier getTestQualifier2(){
        TestQualifier testQualifier = new TestQualifier ();
        testQualifier.setName ("TestQualifier2");
        return testQualifier;
    }
}

打印结果

QualifierTestService---
TestQualifier1
QualifierTestService1---
TestQualifier1
TestQualifier2

总结:
Qualifier标注的bean,可以被Autowired引用到,如果Autowired和Qualifier配合使用,只能获取到标注了Qualifier的bean
介绍完Qualifier,回到LoadBalanced注解分析
首先是自动装配


image.png

LoadBalancerAutoConfiguration类下的重要方法

//获取标注了@LoadBalanced注解的RestTemplate
    @LoadBalanced
    @Autowired(required = false)
    private List<RestTemplate> restTemplates = Collections.emptyList();
    @Bean
    public SmartInitializingSingleton loadBalancedRestTemplateInitializerDeprecated(
//入参为ObjectProvider<List<RestTemplateCustomizer>>
            final ObjectProvider<List<RestTemplateCustomizer>> restTemplateCustomizers) {
        return () -> restTemplateCustomizers.ifAvailable(customizers -> {
//这里的restTemplates就是标注了@LoadBalanced的RestTemplate 
            for (RestTemplate restTemplate : LoadBalancerAutoConfiguration.this.restTemplates) {
                for (RestTemplateCustomizer customizer : customizers) {
                    customizer.customize(restTemplate);
                }
            }
        });
    }

ObjectProvider<List<RestTemplateCustomizer>>作为入参,如何被注入到容器

        @Bean
        @ConditionalOnMissingBean
        public RestTemplateCustomizer restTemplateCustomizer(
                final LoadBalancerInterceptor loadBalancerInterceptor) {
            return restTemplate -> {
                List<ClientHttpRequestInterceptor> list = new ArrayList<>(
                        restTemplate.getInterceptors());
//将拦截器放到restTemplate中,这样就实现了
                list.add(loadBalancerInterceptor);
                restTemplate.setInterceptors(list);
            };
        }

以上的三个代码块都在LoadBalancerAutoConfiguration类中,
这个RestTemplateCustomizer是一个函数性接口,在loadBalancedRestTemplateInitializerDeprecated方法中执行,
而loadBalancedRestTemplateInitializerDeprecated返回的SmartInitializingSingleton依然是函数性接口,
那SmartInitializingSingleton是如何被执行,这里涉及到了spring源码
org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
这个方法的第二个for循环就是,第一个for循环实例化所有的bean,这里就有个问题,如果用 @PostConstruct注解修饰的方法中
用RestTemplate通过微服务名称调用服务的话,是有问题的,因为@PostConstruct会在实例化bean的时候执行,而此时第二个for循环
没有被调用,也就是loadBalancerInterceptor没有加载进RestTemplate中,通过服务名称访问是有问题的.

相关文章

  • @LoadBalanced注解

    @LoadBalanced注解在生产环境使用的不太多,主要是springcloud项目,访问下游服务的时候,用服务...

  • 笔记3-SpringCloud Ribbon

    使用 在创建RestTemplate实例时使用@LoadBalanced注解标注。org.springframew...

  • SpringCloud微服务调用的方式

    ribbon模式使用 @LoadBalanced @Bean 注解修饰 RestTemplate使用服务名调用re...

  • Ribbon源码分析

    先看看@LoadBalanced注解: 这就是一个普通的标记注解,作用就是修饰RestTemplate让其拥有负载...

  • 深入浅出Spring Cloud Ribbon配置

    常用配置 1. 禁用 Eureka当我们在 RestTemplate 上添加 @LoadBalanced 注解后,...

  • ribbon客户端负载均衡

    在消费者中引入 写yml 配置类上加上 注解 @LoadBalanced加上了这个注解之后就配置了RestTemp...

  • Ribbon负载均衡原理

    我们添加了 @LoadBalanced 注解,即可实现负载均衡功能,这是什么原理呢?SpringCloud 底层提...

  • Ribbon源码解析

    1.简单使用1.1.在启动类中,声明一个RestTemplate的bean,用@LoadBalanced注解修饰:...

  • SpringCloud之@LoadBalanced

    SpringCloud是构建在Spring规则之上的代表作。阅读起来很复杂,其中的@LoadBalanced注解堪...

  • ribbon源码解析

    ribbon的使用非常简单,只需要在spring容器中注入一个带有@LoadBalanced注解的RestTmpl...

网友评论

      本文标题:@LoadBalanced注解

      本文链接:https://www.haomeiwen.com/subject/kwdlgrtx.html