负载均衡组件Ribbon核心-@LoadBalanced-上
创始人
2024-03-07 17:15:01
0

引言

书接上篇 微服务负载均衡小能手-Ribbon 使用RIbion实现负载均衡远程调用

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

都知道没有@LoadBalanced注解前,RestTemplate就是一个简单的http请求工具类,贴上该注解,却能山鸡变凤凰,成为具有负载均衡的小能手,为啥呢?本篇就跟你讲讲为啥,开讲之前需要铺垫四个知识储备:

1>@Qualifier  2>SmartInitializingSingleton接口  3>ClientHttpRequestInterceptor拦截器 4>SpringBoot 自动配置

@Qualifier注解详解

Spring 给@Qualifier注解赋予2个功能

1:根据Bean名字注入属性

熟悉的Spring的小伙伴应该能看懂下面的代码:

@Service
public class OrderServiceImpl implements IOrderService {@Autowiredprivate IDiscountService discountService ;  //折扣服务
}

order业务层需要引入折扣业务逻辑,其中的@Autowired 能让Spring将容器中有且唯一的IDiscountService 接口实现类注入到OrderServiceImpl 中。很理想,真实情况是电商项目中的商品折扣种类很多,IDiscountService 接口实现类不会唯一,当spring容器中存在多个IDiscountService 接口实例时,上面代码执行肯定会报错

Field discountService in xxxx.OrderServiceImpl required a single bean, but n were found:

怎么办呢?此时@Qualifier注解就起作用啦。

public interface IDiscountService  {
}@Service("discount1Service")
public class Discount1ServiceImpl  implements IDiscountService  {
}@Service("discount2Service")
public class Discount2ServiceImpl implements IDiscountService  {
}

在定义IDiscountService 接口实现类时,给这些实现类指定Bean名:discount1Service  discount2Service 后续使用时,使用@Qualifier("bean名称")直接指定

@Service
public class OrderServiceImpl implements IOrderService {@Qualifier("discount2Service")  //根据bean名字指定@Autowiredprivate IDiscountService discountService ;  //折扣服务
}

 @Qualifier("xxx") xxx是 Bean 的名称,@Autowired 和 @Qualifier 结合使用时,自动注入的策略就从 byType 转变成 byName 了,完美解决了接口多实现问题。

2:Bean筛选标记符

@Qualifier 注解的这个功能,开发中用途算广,但是Ribbon 负载均衡功能@LoadBalanced 注解刚好用到。

还是上面的接口案例,现在有个需求:将所有IDiscountService接口实现类添加到List集合中

    @Autowiredprivate List list= Collections.emptyList();@Testpublic void testList() {for (IDiscountService discountService : list) {System.out.println(discountService.getClass());}}

执行后,会打印出所有的IDiscountService接口实现类

class com.langfeiyes.demo.Discount1ServiceImpl
class com.langfeiyes.demo.Discount2ServiceImpl

ok,没问题,我们升级一下需求:只需要Discount1ServiceImpl实现类添加到List集合中
此时就需要使用@Qualifier 注解的筛选功能了。

public interface IDiscountService  {
}//不贴,没有筛选标记
@Service("discount1Service")
public class Discount1ServiceImpl  implements IDiscountService  {
}@Qualifier  //贴,筛选标记
@Service("discount2Service")
public class Discount2ServiceImpl implements IDiscountService  {
}

2个接口实现类,只有Discount2ServiceImpl 贴上@Qualifier 标记,集合收集时,配合@Autowired可以实现自动筛选功能

    @Qualifier@Autowired(required = false)private List list= Collections.emptyList();@Testpublic void testList() {for (IDiscountService discountService : list) {System.out.println(discountService.getClass());}}

执行后,会打印出所有的IDiscountService接口实现类

class com.langfeiyes.demo.Discount2ServiceImpl

到这,@Qualifier 注解知识点铺垫算介绍啦,下面看SmartInitializingSingleton 接口

SmartInitializingSingleton 接口

先看下该SmartInitializingSingleton源码

public interface SmartInitializingSingleton {void afterSingletonsInstantiated();
}

SmartInitializingSingleton接口里面只有一个方法:afterSingletonsInstantiated  从方法名也大概看出作用。SmartInitializingSingleton是Spring提供的钩子接口,实现该接口的Bean会在Spring容器初始化所有Bean之后,由容器直接回调afterSingletonsInstantiated  方法。注意:回调的是所有单例Bean。

来一个例子演示一下

public class SomeBean  implements SmartInitializingSingleton {public SomeBean(){System.out.println("我被构建了...");}@Overridepublic void afterSingletonsInstantiated() {System.out.println("我被回调了....");}
}------------------@SpringBoot
class DemoApplication {@Beanpublic SomeBean someBean(){return new SomeBean();}}

查看打印返回值:

我被构建了...
我被回调了....

到这,SmartInitializingSingleton 接口知识点铺垫算介绍啦,下面看 ClientHttpRequestInterceptor拦截器

ClientHttpRequestInterceptor拦截器

截止目前,Spring支持3种http请求拦截器器,分别是

HandlerInterceptor :SpringMVC中组件,拦截普通客户端发起请求,比如:浏览器 ,使用最广的http请求拦截器

ClientHttpRequestInterceptor:spring-web组件,拦截是RestTemplate工具getForEntry/getForObject 发起的http请求,所以常被称之RestTemplate拦截器

RequestInterceptor:spring-cloud-feign组件,拦截是feign发起的远程调用请求,所以称之为Feign拦截器。

本篇重点讲ClientHttpRequestInterceptor拦截器,其他拦截有机会我们再深入。

先看下ClientHttpRequestInterceptor接口源码

@FunctionalInterface
public interface ClientHttpRequestInterceptor {ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)throws IOException;}

ClientHttpRequestInterceptor 接口为函数接口,只有一个intercept拦截方法,在定制拦截器时我们可以根据业务需求为getForEntry/getForObject 方法请求添加额外参数。

需求:getForEntry/getForObject 发起的请求都需要带上身份令牌token

public class RestTokenInterceptor implements ClientHttpRequestInterceptor {@Overridepublic ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {HttpHeaders headers = request.getHeaders();headers.add("token","xxxx");return execution.execute(request,body);}
}

到这,ClientHttpRequestInterceptor拦截器知识点铺垫算介绍啦,下面看:SpringBoot自动配置

SpringBoot自动配置

SpringBoot自动配置之前也写过来,有兴趣的朋友,可以看浅谈SpringBoot 入门合集。

SpringBoot自动配置用下图就可以讲清楚啦:

到这,@LoadBalanced 注解需要的知识储备算准备齐活了,下一篇就是@LoadBalanced注解的源码介绍啦。

相关内容

热门资讯

新春的主持稿 新春的主持稿  在日常生活和工作中,需要使用主持稿的情况越来越多,主持稿是主持人在会议或是节目当中串...
五四青年节的致辞 五四青年节的致辞(通用20篇)  在平日的学习、工作和生活里,大家总少不了要接触或使用致辞吧,致辞是...
新年年会简短优秀致辞 新年年会简短优秀致辞(通用8篇)  在生活、工作和学习中,大家都不可避免地会接触到致辞吧,致辞具有很...
告别仪式的主持词 告别仪式的主持词3篇  告别主持词篇一:  男:离别,是一个沉重的动词。  女:离别,一个让人一生难...
喜爱夜蒲2经典台词 喜爱夜蒲2经典台词  1、做要做到最好,玩要玩到最尽。  2、我们明知不能相爱,可还是相爱了,未曾绽...
领导年会致辞 领导年会致辞  无论在学习、工作或是生活中,大家对致辞都不陌生吧,致辞是指在举行会议或某种仪式时具有...
关于保险公司年会主持词 关于保险公司年会主持词  公司的类型有哪些  根据《中华人民共和国公司法》公司的主要形式为无限责任公...
在年会上的致辞 在年会上的致辞范文(精选5篇)  在平时的学习、工作或生活中,大家都写过致辞吧,致辞是指在举行会议或...
企业开工仪式致辞 企业开工仪式致辞(精选7篇)  在平时的学习、工作或生活中,大家都不可避免地会接触到致辞吧,致辞是指...
小学第二学期的开学典礼主持词 小学第二学期的开学典礼主持词  主持词已成为各种演出活动和集会中不可或缺的一部分。在当今中国社会,各...
升学宴主持词 升学宴主持词3篇  高考过后考生及家长需要考虑举办升学宴会酒席的事宜了,升学宴主持词怎么写?下面是小...
同学聚会致辞 同学聚会致辞(精选6篇)  在生活、工作和学习中,大家都尝试过写致辞吧,在各种重大的庆典、外交、纪念...
升学宴会主持词 升学宴会主持词9篇  主持人在台上表演的灵魂就表现在主持词中。在当今社会中,各种场合中活跃现场气氛的...
早会主持词 早会主持词范文4篇  早会能对一天或是一周亦或是一个月的工作作出及时的总结和临时性的调整,在工作中有...
服装展示主持词示例 服装展示主持词示例  篇一:服装展示串词  龙 蓓  1、现在出场的是宾馆总台接待,为大家作展示的是...
重阳节主持词 重阳节主持词(精选13篇)  主持词分为会议主持词、晚会主持词、活动主持词、婚庆主持词等。在人们越来...
商场活动主持词   商场活动主持词  亲爱的顾客朋友:  大家下午好!  “金猪报捷去,玉鼠送春来”。欢迎大家在这个...
主婚人简短婚礼致辞 主婚人简短婚礼致辞  结婚是件大事,那么主婚人如何向新人们致辞呢?怎么做致辞才简短又大气呢?下面我们...
六一儿童节活动主持词 六一儿童节活动主持词集锦  众所周知,六一儿童节是孩子们开心玩耍的节日。小编今天为大家带来六一儿童节...