@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;
}
- 获取@HystrixCommand注解的属性
- 根据方法的返回类型判断是同步还是异步的,这里有三种方式 同步(SYNCHRONOUS),异步(ASYNCHRONOUS),响应式(OBSERVABLE) 如果是 Future.class返回类型的为异步,如果是 (Observable.class, Single.class, Completable.class) 这三种类型中一种,为OBSERVABLE ,剩下的类型为 同步方式
- 构建MetaHolder&#