Spring Cloud——Hystrix源码分析(工作流程)

@EnableHystrix

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@EnableCircuitBreaker
public @interface EnableHystrix {
}

@EnbaleHystrix引入了@EableCircuitBreaker。继续查看源码

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

}

引入了EnableCircuitBreakerImportSelector.class,这个类继承了SpringFactoryImportSelector,

作用应该是手动注入特定的Bean,看源码:

@Override
	public String[] selectImports(AnnotationMetadata metadata) {
        //判断是否开启Hystrix
		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
		List<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 factory
			this.log.warn("More than one implementation " + "of @" + getSimpleName()
					+ " (now relying on @Conditionals to pick one): " + factories);
		}

		return factories.toArray(new String[factories.size()]);
	}

判断是否开启Hystrix,如果没有开启,直接返回

获取到所有的配置,SpringFactoryImportSelector 类实现了BeanClassLoadAware,获得类加载器,是SpringBoot将需要注入的Bean放在META-INF/spring.factories文件中。加载@EableCircuitBreaker注解需要注入的配置实现类:org.springframework.cloud.netflix.hystrix.HystrixCircuitBreakerConfiguration

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.netflix.hystrix.HystrixAutoConfiguration,\
org.springframework.cloud.netflix.hystrix.HystrixCircuitBreakerAutoConfiguration,\
org.springframework.cloud.netflix.hystrix.security.HystrixSecurityAutoConfiguration

org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker=\
org.springframework.cloud.netflix.hystrix.HystrixCircuitBreakerConfiguration

追踪HystrixCircuitBreakerConfiguration源码:

@Configuration(
    proxyBeanMethods = false
)
public class HystrixCircuitBreakerConfiguration {
    public HystrixCircuitBreakerConfiguration() {
    }

    //注入一个拦截器
    @Bean
    public HystrixCommandAspect hystrixCommandAspect() {
        return new HystrixCommandAspect();
    }

   }


    @Bean
    public HystrixCircuitBreakerConfiguration.HystrixShutdownHook hystrixShutdownHook() {
        return new HystrixCircuitBreakerConfiguration.HystrixShutdownHook();
    }

    @Bean
    public HasFeatures hystrixFeature() {
        return HasFeatures.namedFeatures(new NamedFeature[]{new NamedFeature("Hystrix", HystrixCommandAspect.class)});
    }

    private class HystrixShutdownHook implements DisposableBean {
        private HystrixShutdownHook() {
        }

        public void destroy() throws Exception {
            Hystrix.reset();
        }
    }
}

从这个自动配置可以看出主要是注入一个拦截器HystrixCommandAspect。查看源码:

HystrixCommandAspect:

HystrixCommandAspect类中有一个META_META_HOLDER_FACTORY_MAP属性,这个里面放的是不同类型对应的MetaHolder的Factory:

@Aspect
public class HystrixCommandAspect {
   //省略代码

 static {
        META_HOLDER_FACTORY_MAP = ImmutableMap.builder().put(HystrixCommandAspect.HystrixPointcutType.COMMAND, new HystrixCommandAspect.CommandMetaHolderFactory()).put(HystrixCommandAspect.HystrixPointcutType.COLLAPSER, new HystrixCommandAspect.CollapserMetaHolderFactory()).build();
    }

}

CommandMetaHolderFactory和CollasperMetaHolderFactory都是继承了 抽象类MetaHolderFactory,作用就是 根据不同的类型创建一个MetaHolder ,MetaHolder 里面包含了当前方法 所需的各种必要信息 。以CommandMetaHoldFactory为例,分析其create方法:

 public MetaHolder create(Object proxy, Method method, Object obj, Object[] args, ProceedingJoinPoint joinPoint) {
            HystrixCommand hystrixCommand = (HystrixCommand)method.getAnnotation(HystrixCommand.class);
            ExecutionType executionType = ExecutionType.getExecutionType(method.getReturnType());
            Builder builder = this.metaHolderBuilder(proxy, method, obj, args, joinPoint);
            if (EnvUtils.isCompileWeaving()) {
                builder.ajcMethod(HystrixCommandAspect.getAjcMethodFromTarget(joinPoint));
            }

            return builder.defaultCommandKey(method.getName()).hystrixCommand(hystrixCommand).observableExecutionMode(hystrixCommand.observableExecutionMode()).executionType(executionType).observable(ExecutionType.OBSERVABLE == executionType).build();
        }


  Builder metaHolderBuilder(Object proxy, Method method, Object obj, Object[] args, ProceedingJoinPoint joinPoint) {
            Builder builder = MetaHolder.builder().args(args).method(method).obj(obj).proxyObj(proxy).joinPoint(joinPoint);
            HystrixCommandAspect.setFallbackMethod(builder, obj.getClass(), method);
            builder = HystrixCommandAspect.setDefaultProperties(builder, obj.getClass(), joinPoint);
            return builder;
        }
  1. 获取@HystrixCommand注解的属性
  2. 根据方法的返回类型判断是同步还是异步的,这里有三种方式 同步(SYNCHRONOUS),异步(ASYNCHRONOUS),响应式(OBSERVABLE) 如果是 Future.class返回类型的为异步,如果是 (Observable.class, Single.class, Completable.class) 这三种类型中一种,为OBSERVABLE ,剩下的类型为 同步方式
  3. 构建MetaHolder&#
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值