Ribbon中@LoadBalanced注解的原理

写在前面的话

最近在研究Ribbon源码的过程中,一直想不明白@LoadBalanced注解的原理,因为我一直找不到解析这个注解的类在哪。

直接我看见了@LoadBalanced注解上还打了一个@Qualifier注解,我顿悟,这个注解肯定跟@Qualifier注解有关系

1、@Qualifier注解的作用

假设有一个接口UserService,该接口有两个实现类,分别为AUserServiceImpl,BUserServiceImpl,这两个实现类都注册为spring的bean,如下所示

public interface UserService {
}

@Service
public class AUserServiceImpl implements UserService  {
}

@Service
public class BUserServiceImpl implements UserService  {
}

那么在controller中依赖注入的时候,如果用@Autowired注解注入,则势必会报错,就像下面一样

@Autowired
private UserService userService;

因为@Autowired是按Bean的类型装配,而此时有两个UserService类型的Bean,则注入的时候spring不知道你到底想要注入哪个Bean,索性直接报错了

该问题有几种解决方法,如下:

方法一:

采用@Resource注解,如下所示:

@Resource
private  UserService AUserServiceImpl;

方法二:

采用List类型,如下所示:

@Autowired
private  List<UserService> userServiceList;

此时有再多的UserService类型的Bean也不怕了,因为统统都会被放到List里面去

方法三:

采用@Qualifier注解。Qualifier是合格者的意思,表示为多个实现类选一个合格者注入,如下所示

@Autowired
@Qualifier("AUserServiceImpl")
private  UserService userService;

@Qualifier注解的基本作用就先讲到这了

2、Ribbon中的@LoadBalanced注解

本文的目的是利用Ribbon中@LoadBalanced注解,来介绍spring的@Qualifier注解的使用小技巧,不会Ribbon的小伙伴也能读懂,因此本文就不介绍Ribbon的相关知识了

有兴趣的小伙伴们可以看我的这篇文章,这里面有Ribbon的原理和实战相关的内容,非常详细 Spring Cloud教程 第二弹 客户端负载均衡Ribbon

@LoadBalanced注解的源码如下(@LoadBalanced注解上打了一个@Qualifier注解,因此@LoadBalanced是@Qualifier的子类):

package org.springframework.cloud.client.loadbalancer;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.beans.factory.annotation.Qualifier;

@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Qualifier
public @interface LoadBalanced {

}

在Ribbon中有一个自动配置类,其关键代码如红框部分所示(别的不用看):

另外,使用过Ribbon的小伙伴们肯定都知道,还需要如下配置才能让负载均衡生效:

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

上述有三块代码,分别称为第一块代码、第二块代码、第三块代码

经过我一番思考,于是我大胆地提出猜想:

  • 第一块代码中,由于@LoadBalanced是@Qualifier的子类,那么@LoadBalanced也具有@Qualifier的特性
  • 第二块代码中,LoadBalancerAutoConfiguration类的restTemplates属性上打了@Autowired注解,表示将所有RestTemplate类型的Bean注入到该集合中,并且还打了@LoadBalanced注解,则注入的筛选条件是:具有负载均衡标识的RestTemplate
  • 第三块代码中,恰恰用@Bean和@LoadBalanced注解声明了一个RestTemplate类型的bean

3、验证猜想

3.1、自定义注解

@Target({ ElementType.TYPE,ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Qualifier
public @interface LoadBalancedCopy {
}

3.2、定义Bean

现在接口UserService和五个实现类,五个实现类中有2个实现类打上@LoadBalancedCopy注解

public interface UserService {
}

@Service
public class AUserServiceImpl implements UserService  {
}

@Service
@LoadBalancedCopy
public class BUserServiceImpl implements UserService  {
}

@Service
public class CUserServiceImpl implements UserService  {
}

@Service
@LoadBalancedCopy
public class DUserServiceImpl implements UserService  {
}

@Service
public class EUserServiceImpl implements UserService  {
}

3.3、注入

@RestController
@RequestMapping("/common")
public class CommonController {

    @Autowired
    @LoadBalancedCopy
    private  List<UserService> userServiceList;

    @RequestMapping("/beanInfo")
    public void beanInfo(){
        System.out.println(userServiceList.size());
        for (UserService userService : userServiceList) {
            System.out.println(userService.getClass().getName());
        }
    }

}

3,4、运行测试

访问http://localhost:8160/springboot-common-base/common/beanInfo  控制台打印信息如下

由此可见,我的猜想是正确的

总结

本文主要介绍了@Qualifier注解的作用,并且由Ribbon的@LoadBalanced注解,引出了@Qualifier注解的小技巧

顺带着也把@LoadBalanced注解的原理也讲了

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

波波老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值