Spring cloud - Hystrix源码

其实只是Hystrix初始化部分,我们从源码的角度分析一下@EnableCircuitBreaker以及@HystrixCommand注解的初始化过程。

从@EnableCircuitBreaker入手

我们是通过在启动类添加@EnableCircuitBreaker注解启用Hystrix的,所以,源码解析也要从这个注解入手。

该注解已经被标了@Deprecated了,不过,挡不住…

Spring关于@Enablexxxx注解的套路:通过@Import注解引入了EnableCircuitBreakerImportSelector.class:

@Deprecated
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(EnableCircuitBreakerImportSelector.class)
public @interface EnableCircuitBreaker {}

跟踪EnableCircuitBreakerImportSelector,继承自SpringFactoryImportSelector,注意SpringFactoryImportSelector类的泛型类型为EnableCircuitBreaker:

@Order(Ordered.LOWEST_PRECEDENCE - 100)
public class EnableCircuitBreakerImportSelector extends SpringFactoryImportSelector<EnableCircuitBreaker> {@Overrideprotected boolean isEnabled() {return getEnvironment().getProperty("spring.cloud.circuit.breaker.enabled", Boolean.class, Boolean.TRUE);}}

看一下类图:
在这里插入图片描述

属性annotationClass通过GenericTypeResolver.resolveTypeArgument方法获取当前对象的泛型参数的具体类型,现在我们知道是EnableCircuitBreaker(在org.springframework.cloud.client.circuitbreaker包下)。

public abstract class SpringFactoryImportSelector<T>implements DeferredImportSelector, BeanClassLoaderAware, EnvironmentAware {private final Log log = LogFactory.getLog(SpringFactoryImportSelector.class);private ClassLoader beanClassLoader;private Class<T> annotationClass;private Environment environment;@SuppressWarnings("unchecked")protected SpringFactoryImportSelector() {this.annotationClass = (Class<T>) GenericTypeResolver.resolveTypeArgument(this.getClass(),SpringFactoryImportSelector.class);}

@Import注解我们前面做过详细分析了,实现了DeferredImportSelector接口表示延迟加载全限定名称为selectImports方法返回的类。看selectImports方法:

@Overridepublic String[] selectImports(AnnotationMetadata metadata) {//Enable参数没有打开的话就不加载if (!isEnabled()) {return new String[0];}AnnotationAttributes attributes = AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(this.annotationClass.getName(), true));Assert.notNull(attributes, "No " + getSimpleName() + " attributes found. Is " + metadata.getClassName()+ " annotated with @" + getSimpleName() + "?");// Find all possible auto configuration classes, filtering duplicates//SPI机制调用spring.factories文件下的EnableCircuitBreakerList<String> factories = new ArrayList<>(new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(this.annotationClass, this.beanClassLoader)));if (factories.isEmpty() && !hasDefaultFactory()) {throw new IllegalStateException("Annotation @" + getSimpleName()+ " found, but there are no implementations. Did you forget to include a starter?");}if (factories.size() > 1) {// there should only ever be one DiscoveryClient, but there might be more than// one factorythis.log.warn("More than one implementation " + "of @" + getSimpleName()+ " (now relying on @Conditionals to pick one): " + factories);}return factories.toArray(new String[factories.size()]);}

selectImports方法的主要功能就是调用SpringFactoriesLoader.loadFactoryNames方法,该方法的目的是通过SPI机制读取spring.factories文件中的org.springframework.cloud.client.circuitbreaker相关配置,返回。

返回的信息是类全限定名,从selectImports方法作用可知,这些类会加载到Spring Ioc容器中。

org.springframework.cloud.client.circuitbreaker在spring-cloud-netflix-hystrix-2.2.10.RELEASE包下:
org.springframework.cloud.client.circuitbreaker
所以该配置下的org.springframework.cloud.netflix.hystrix.HystrixCircuitBreakerConfiguration会被调用并加载到Spring IoC容器中。

HystrixCircuitBreakerConfiguration

跟踪配置类HystrixCircuitBreakerConfiguration:


/*** @author Spencer Gibb* @author Christian Dupuis* @author Venil Noronha*/
@Configuration(proxyBeanMethods = false)
public class HystrixCircuitBreakerConfiguration {@Beanpublic HystrixCommandAspect hystrixCommandAspect() {return new HystrixCommandAspect();}@Beanpublic HystrixShutdownHook hystrixShutdownHook() {return new HystrixShutdownHook();}

注入了一个叫HystrixCommandAspect 的bean,从名字上看,应该是关于HystrixCommand的切面,用到了AOP。其实也容易理解,加了@HystrixCommand注解的方法的执行逻辑发生了变化:方法增强了执行时长是否超时、执行是否成功(是否返回异常)、超时或异常的情况下调用fallback…方法功能的增强正是AOP的强项。

继续跟踪HystrixCommandAspect 类。

HystrixCommandAspect

打开代码,首先是非常熟悉的@Aspect注解:

@Aspect
public class HystrixCommandAspect {

表明当前类是AOP的切面。

继续看代码:

@Pointcut("@annotation(com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand)")public void hystrixCommandAnnotationPointcut() {}@Pointcut("@annotation(com.netflix.hystrix.contrib.javanica.annotation.HystrixCollapser)")public void hystrixCollapserAnnotationPointcut() {}@Around("hystrixCommandAnnotationPointcut() || hystrixCollapserAnnotationPointcut()")public Object methodsAnnotatedWithHystrixCommand(final ProceedingJoinPoint joinPoint) throws Throwable {

添加了针对注解HystrixCommand的切点,以及针对该切点的环绕增强方法methodsAnnotatedWithHystrixCommand。

最终的熔断、限流、服务降级功能,都是在这个methodsAnnotatedWithHystrixCommand方法里实现的,继续向下研究这个方法的代码逻辑,需要RxJava背景知识做支撑。

有空再聊:) ~!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/207123.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

雷电模拟器打开指针位置无效果解决方法(开发者模式)

预期效果 1.打开文件所在位置 2.进入vms目录 3.新建一个名为debug的txt格式的文件 4.打开开发者模式里面指针位置的选项 5.重启模拟器 6.噔噔噔噔~

面试官:什么是三色标记

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一波电子书籍资料&#xff0c;包含《Effective Java中文版 第2版》《深入JAVA虚拟机》&#xff0c;《重构改善既有代码设计》&#xff0c;《MySQL高性能-第3版》&…

最新PHP熊猫头图片表情斗图生成源码

这是一款能生成熊猫头表情斗图的自适应系统源码&#xff0c;无论是在电脑还是手机上都可以正常使用&#xff01;这个源码集成了搜狗搜索图片接口&#xff0c;可以轻松地一键搜索数百万张图片&#xff0c;并且还包含了表情制作等功能模块。对于一些新站来说&#xff0c;这是一个…

功率放大器在无线收发系统中的作用

功率放大器在无线收发系统中也扮演着至关重要的角色。无线通信是一种通过电磁波传输信息的技术&#xff0c;它具有便捷、灵活、广覆盖等优势&#xff0c;在现代社会得到了广泛应用。而功率放大器则是无线收发系统中的核心组件之一&#xff0c;主要用于增强信号的功率和距离。下…

代码规范之-理解ESLint、Prettier、EditorConfig

前言 团队多人协同开发项目&#xff0c;困扰团队管理的一个很大的问题就是&#xff1a;无可避免地会出现每个开发者编码习惯不同、代码风格迥异&#xff0c;为了代码高可用、可维护性&#xff0c;需要从项目管理上尽量统一和规范代码。理想的方式需要在项目工程化方面&#xff…

飞书CEO谢欣:绝大部分企业希望拥抱AI,但并未做好准备

11月22日&#xff0c;飞书在北京举办了产品发布会&#xff0c;正式发布“飞书智能伙伴”等系列AI产品。“飞书智能伙伴”有知识、有记忆&#xff0c;有主动性&#xff0c;也能深入到业务中。在内容创作、内容总结、数据分析、场景构建、系统搭建等业务场景&#xff0c;用户均可…

代码随想录二刷 |链表 | 链表总结

代码随想录二刷 &#xff5c;链表 &#xff5c; 链表总结 理论基础分类单链表双链表环形链表 存储方式链表的定义链表操作删除链表节点添加链表节点 性能分析 移除链表元素在原链表上移除虚拟头节点移除 设计链表反转链表双指针递归 两两交换链表节点移除链表的倒数第 N 个节点…

BUUCTF 梅花香之苦寒来 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 注意&#xff1a;得到的 flag 请包上 flag{} 提交 密文&#xff1a; 下载附件&#xff0c;解压得到一张.jpg图片。 解题思路&#xff1a; 1、用010 Editor看了一下&#xff0c;刚开始以为是修改宽高的题&#xff…

智能安全帽作业记录仪赋能智慧工地人脸识别劳务实名制

需求背景 建筑工地是一个安全事故多发的场所。目前&#xff0c;工程建设规模不断扩大&#xff0c;工艺流程纷繁复杂&#xff0c;如何完善现场施工现场管理&#xff0c;控制事故发生频率&#xff0c;保障文明施工一直是施工企业、政府管理部门关注的焦点。尤其随着社会的不断进…

dolphinscheduler有任务一直在运行(问题)目前对数据库解决

dolphinscheduler有任务一直在运行&#xff08;问题&#xff09;目前对数据库解决 危害&#xff1a; 这么多的任务没有结束&#xff0c;会涉及很多问题的&#xff0c;系统的数据盘会不断入职日志&#xff0c;数据量很大&#xff0c; 其实对于dolphinscheduler的性能是下降的&a…

【C++容器】优先级队列 仿函数 反向迭代器

优先级队列&#xff0c;仿函数&#xff0c;反向迭代器 优先级队列认识优先级队列模拟实现优先级队列 浅谈仿函数仿函数的大致了解仿函数的实现 反向迭代器什么是反向迭代器&#xff1f;反向迭代器的实现 结语 优先级队列 认识优先级队列 优先级队列&#xff08;priority_queue…

实现centos7与windows共享文件夹

第一步 点击设置 第二步 第三步 第四步 让共享文件夹挂载到hgfs目录下 输入如下命令: sudo vmhgfs-fuse .host:/ /mnt/hgfs -o subtypevmhgfs-fuse,allow_other完成共享