SpringCloud Hystrix

1、样例

/**
 * http://127.0.0.1:8080/user/hello
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserClient userClient;

    @RequestMapping("/hello")
    public String hello() {
        return userClient.sayHello();
    }

}

 

import home.spring.cloud.Hystrix.UserClientFallback;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;

@FeignClient(value = "user", fallback = UserClientFallback.class)
public interface UserClient {

    @RequestMapping("/users/222")
    String sayHello();

}

 

import home.spring.cloud.Feign.UserClient;
import org.springframework.stereotype.Component;

@Component
public class UserClientFallback implements UserClient {
    @Override
    public String sayHello() {
        return "Oh! Error!!!";
    }
}

 

当UserController.hello中,去调用userClient接口方法时,其实调用的是一个代理类,代理类如下

feign.hystrix.HystrixInvocationHandler#invoke 下面是该方法的主要逻辑

 HystrixCommand<Object> hystrixCommand = new HystrixCommand<Object>(setterMethodMap.get(method)) {
    @Override
    protected Object run() throws Exception {
      try {
        return HystrixInvocationHandler.this.dispatch.get(method).invoke(args);
      } catch (Exception e) {
        throw e;
      } catch (Throwable t) {
        throw (Error) t;
      }
    }

    @Override
    protected Object getFallback() {
      if (fallbackFactory == null) {
        return super.getFallback();
      }
      try {
        Object fallback = fallbackFactory.create(getExecutionException());
        Object result = fallbackMethodMap.get(method).invoke(fallback, args);
        if (isReturnsHystrixCommand(method)) {
          return ((HystrixCommand) result).execute();
        } else if (isReturnsObservable(method)) {
          // Create a cold Observable
          return ((Observable) result).toBlocking().first();
        } else if (isReturnsSingle(method)) {
          // Create a cold Observable as a Single
          return ((Single) result).toObservable().toBlocking().first();
        } else if (isReturnsCompletable(method)) {
          ((Completable) result).await();
          return null;
        } else {
          return result;
        }
      } catch (IllegalAccessException e) {
        // shouldn't happen as method is public due to being an interface
        throw new AssertionError(e);
      } catch (InvocationTargetException e) {
        // Exceptions on fallback are tossed by Hystrix
        throw new AssertionError(e.getCause());
      }
    }
  };

  if (isReturnsHystrixCommand(method)) {
    return hystrixCommand;
  } else if (isReturnsObservable(method)) {
    // Create a cold Observable
    return hystrixCommand.toObservable();
  } else if (isReturnsSingle(method)) {
    // Create a cold Observable as a Single
    return hystrixCommand.toObservable().toSingle();
  } else if (isReturnsCompletable(method)) {
    return hystrixCommand.toObservable().toCompletable();
  }
  return hystrixCommand.execute();
}

一目了然,直接新建一个HystrixCommand对象,进行调用实际的rpc接口

 

 

HystrixInvocationHandler 这类对象什么时候创建的?

首先要加注解  @EnableFeignClients

启动的时候,spring初始化beanDefined对象(UserClient userClient)时候,reflush()   中间有一个步骤

invokeBeanFactoryPostProcessors(beanFactory)   上述的handler代理类是通过Factory生成的

步骤调用了org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions

经过org.springframework.context.annotation.ConfigurationClassParser#parse(java.util.Set<org.springframework.beans.factory.config.BeanDefinitionHolder>)

protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {

 

protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
        throws IOException {

 

private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
        Collection<SourceClass> importCandidates, boolean checkForCircularImports) {

 这个方法里面解析了注解@Import

这样就直接调用到了

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(FeignClientsRegistrar.class)
public @interface EnableFeignClients {
class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar,
      ResourceLoaderAware, EnvironmentAware {

   // patterned after Spring Integration IntegrationComponentScanRegistrar
   // and RibbonClientsConfigurationRegistgrar

   private ResourceLoader resourceLoader;

   private Environment environment;

   public FeignClientsRegistrar() {
   }

   @Override
   public void setResourceLoader(ResourceLoader resourceLoader) {
      this.resourceLoader = resourceLoader;
   }

   @Override
   public void registerBeanDefinitions(AnnotationMetadata metadata,     // 直接调用此方法注册一些代理类
         BeanDefinitionRegistry registry) {
      registerDefaultConfiguration(metadata, registry);
      registerFeignClients(metadata, registry);
   }

   private void registerDefaultConfiguration(AnnotationMetadata metadata,
         BeanDefinitionRegistry registry) {
      Map<String, Object> defaultAttrs = metadata
            .getAnnotationAttributes(EnableFeignClients.class.getName(), true);

      if (defaultAttrs != null && defaultAttrs.containsKey("defaultConfiguration")) {

 

直接生成

FeignClientFactoryBean   getObject生成新代理对象
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值