@EnableCircuitBreaker

咱们应用hystrix的时候,都会在application上应用@EnableCircuitBreaker注解,咱们看看这个主键到底做了什么事件。
他import了EnableCircuitBreakerImportSelector,看到ImportSelector咱们应该会联想到,他前面可能有某些bean会被注入到IOC容器中。

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

咱们跟着看EnableCircuitBreakerImportSelector,这里会有isEnabled办法,他的实现类SpringFactoryImportSelector我这里就不说了。他的意思是,如果返回true的时候,会从spring.factories中读取org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker对应的HystrixCircuitBreakerConfiguration,最初这个HystrixCircuitBreakerConfiguration就会被实例化。这个类被加载后,他会紧接着加载HystrixCommandAspect,一看到Aspect,就晓得AOP吧。咱们看看他用这个干吗。

public class EnableCircuitBreakerImportSelector        extends SpringFactoryImportSelector<EnableCircuitBreaker> {    @Override    protected boolean isEnabled() {        return getEnvironment().getProperty("spring.cloud.circuit.breaker.enabled",                Boolean.class, Boolean.TRUE);    }}

HystrixCommandAspect

他这里定义了一个@Pointcut,咱们平时用hystrix的时候,就是会加HystrixCommand吧,当初晓得为什么要加这个注解了吧,他会通过AOP拦挡代理相应办法。

@Pointcut("@annotation(com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand)")public void hystrixCommandAnnotationPointcut() {}

HystrixCommand注解有多个配置的参数,比方:

  • groupKey:命令分组键,能够依据这个分组,统计他的各个指标,默认类名。
  • commandKey:命令键,默认办法名。
  • threadPoolKey:线程池名,如果没有设置,默认为groupKey。
  • fallbackMethod:服务降级调用的办法。
  • threadPoolProperties:配置线程池用的。

当然还有其余,就不一一列了。
上面咱们看看办法,这里次要是通过咱们配置的信息,生成一个GenericCommand对象,通过这个对象调用execute办法。

@Around("hystrixCommandAnnotationPointcut() || hystrixCollapserAnnotationPointcut()")public Object methodsAnnotatedWithHystrixCommand(final ProceedingJoinPoint joinPoint) throws Throwable {    Method method = getMethodFromTarget(joinPoint);    Validate.notNull(method, "failed to get method from joinPoint: %s", joinPoint);    if (method.isAnnotationPresent(HystrixCommand.class) && method.isAnnotationPresent(HystrixCollapser.class)) {        throw new IllegalStateException("method cannot be annotated with HystrixCommand and HystrixCollapser " +                "annotations at the same time");    }    // 依据注解获取CommandMetaHolderFactory还是CollapserMetaHolderFactory    MetaHolderFactory metaHolderFactory = META_HOLDER_FACTORY_MAP.get(HystrixPointcutType.of(method));    // 通过配置信息生成元数据    MetaHolder metaHolder = metaHolderFactory.create(joinPoint);    // 创立GenericCommand,会把元数据的信息赋值到GenericCommand的属性中。    // 除此,线程池、commandActions也是这里    HystrixInvokable invokable = HystrixCommandFactory.getInstance().create(metaHolder);    ExecutionType executionType = metaHolder.isCollapserAnnotationPresent() ?            metaHolder.getCollapserExecutionType() : metaHolder.getExecutionType();    Object result;    try {        if (!metaHolder.isObservable()) {            // 这里会把GenericCommand强制转为HystrixExecutable,而后调用execute办法            result = CommandExecutor.execute(invokable, executionType, metaHolder);        } else {            result = executeObservable(invokable, executionType, metaHolder);        }    } catch (HystrixBadRequestException e) {        throw e.getCause();    } catch (HystrixRuntimeException e) {        throw hystrixRuntimeExceptionToThrowable(metaHolder, e);    }    return result;}

把GenericCommand转为HystrixExecutable对象。

public static Object execute(HystrixInvokable invokable, ExecutionType executionType, MetaHolder metaHolder) throws RuntimeException {    // 其余略    return castToExecutable(invokable, executionType).execute();    // 其余略    }private static HystrixExecutable castToExecutable(HystrixInvokable invokable, ExecutionType executionType) {    if (invokable instanceof HystrixExecutable) {        return (HystrixExecutable) invokable;    }    // 其余略    }

总结

@EnableCircuitBreaker次要是为了加载HystrixCircuitBreakerConfiguration以及HystrixCommandAspect,通过AOP代理咱们的办法,熔断、限流,就是在这里开始的。