Feign下的数据传递

在Spring Cloud Feign的框架下,远程调用一般需要引入Hystrix来熔断限流。hystrix默认是以线程池进行资源隔离,也就是说当一个线程准备发起Feign调用时,真正进行网络请求的动作是在hystrix中的线程池中进行的。如果此时我们想要编写feign拦截器做一些自定义的事情,那么将无法获取调用线程中的数据。

比如,在拦截器中我们想把每次请求的用户信息带上,如果直接采用ThreadLocal来实现是行不通的,ThreadLocal无法做到将数据从调用线程传到线程池中。

 

hystrix提供了一种解决方案HystrixRequestVariableDefault

这里封装了一个小工具可以实现数据传递的功能。

public class TestController {

    @Resource
    private PeopleClient peopleClient;

    @GetMapping("/getMap")
    public Response<List<Object>> getAll(@RequestParam("name") String name) {

        // 设置需要传递的数据
        UserTraceContext.initializeContext();
        UserSession session = new UserSession();
        session.setName(name);
        UserTraceContext.setData(session);

        List<Object> list = new ArrayList<>();
        list.add(peopleClient.getPeopleEx());
        Object data = UserTraceContext.getData();
        log.info("Who get map = {}", ((UserSession)data).getName());
        
        return new Response(list);
    }

    @GetMapping("/getPeopleEx")
    public Response<People> getPeopleEx() {
        return new Response<People>(new People());
    }
}

 

@Component
@Slf4j
public class BizInterceptor implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate template) {
        // 拦截器中可以获取数据
        log.info("**********this is a biz interceptor******");
        Object data = UserTraceContext.getData();
        log.info("Who get map = {}", ((UserSession)data).getName());

        // 打印为null
        log.info("threadLocal = {}", CacheManager.threadLocal.get());
        log.info("**********this is a biz interceptor******");
    }
}

代码使用了一个封装的小工具,源码参见 https://github.com/markytsai/context-util

 

上一篇:open-feign拦截器


下一篇:Ribbon和Feign的区别