网站建设微分销,河北建设工程信息网天行建和园,芜湖县住房建设局网站,网站建设代码实例其实只是Hystrix初始化部分#xff0c;我们从源码的角度分析一下EnableCircuitBreaker以及HystrixCommand注解的初始化过程。
从EnableCircuitBreaker入手
我们是通过在启动类添加EnableCircuitBreaker注解启用Hystrix的#xff0c;所以#xff0c;源码解析也要从这个注解…其实只是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 SpringFactoryImportSelectorEnableCircuitBreaker {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 SpringFactoryImportSelectorTimplements DeferredImportSelector, BeanClassLoaderAware, EnvironmentAware {private final Log log LogFactory.getLog(SpringFactoryImportSelector.class);private ClassLoader beanClassLoader;private ClassT annotationClass;private Environment environment;SuppressWarnings(unchecked)protected SpringFactoryImportSelector() {this.annotationClass (ClassT) 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文件下的EnableCircuitBreakerListString 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.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背景知识做支撑。
有空再聊:) ~!