Netflix Feign - Spring Cloud 整合 Feign 源码(五)

107 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。


6. 创建feign动态代理

基于Feign.Builder和HardCodedTarget,通过JDK原生动态代理机制,针对接口创建动态代理对象。

Targeter

在FeignAutoConfiguration中,创建Targeter子类HystrixTargeter。

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(name = "feign.hystrix.HystrixFeign")
protected static class HystrixFeignTargeterConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public Targeter feignTargeter() {
        return new HystrixTargeter();
    }

}

@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingClass("feign.hystrix.HystrixFeign")
protected static class DefaultFeignTargeterConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public Targeter feignTargeter() {
        return new DefaultTargeter();
    }

}

如果有feign.hystrix.HystrixFeign这个类的话,那么就会构造一个HystrixTargeter出来;如果没有feign.hystrix.HystrixFeign这个类的话,那么就会构造一个DefaultTargeter出来

Feign.Builder

启用feign.hystrix.enabled,feign与hystrix整合,使用HystrixFeign.Builder。

默认的情况下,Feign.Builder使用feign原生的Feign.Builder。

ParseHandlersByName

Map<String, MethodHandler> nameToHandler = targetToHandlersByName.apply(target);
Map<Method, MethodHandler> methodToHandler = new LinkedHashMap<Method, MethodHandler>();

targetToHandlersByName(ParseHandlersByName)基于配置的Contract, Options, Encoder, Decoder, QueryMapEncoder, ErrorDecoder, SynchronousMethodHandler.Factory等组件,应用到Target对象(HardCodedTarget(type=ProductFacadeServiceFeign, name=eureka-provider-ribbon-feign-api-impl, url=http://eureka-provider-ribbon-feign-api-impl)),解析接口上所有的Spring Mvc的注解,以及接口中各个方法封装成MethodHandler(SynchronousMethodHandler:同步方法代理处理器组件),返回方法名方法处理器的map

遍历ProductFacadeServiceFeign接口中的每个方法,重新映射成方法对象方法处理器的map(动态代理中作为Method对象的dispatch)

methodToHandler.put(method, nameToHandler.get(Feign.configKey(target.type(), method)));

nameToHandler:接口中的每个方法的名称,对应一个处理方法的SynchronousMethodHandler

methodToHandler:接口中的每个方法对应的Method对象,对应一个处理方法的SynchronousMethodHandler

// InvocationHandlerFactory factory
InvocationHandler handler = factory.create(target, methodToHandler);

基于InvocationHandlerFactory工厂,创建一个动态代理InvocationHandler调用处理器。

static final class Default implements InvocationHandlerFactory {

    @Override
    public InvocationHandler create(Target target, Map<Method, MethodHandler> dispatch) {
        return new ReflectiveFeign.FeignInvocationHandler(target, dispatch);
    }
}
T proxy = (T) Proxy.newProxyInstance(target.type().getClassLoader(), new Class<?>[] {target.type()}, handler);

基于JDK的动态代理,创建一个动态代理Proxy。Proxy实现ProductFacadeServiceFeign接口。

new Class<?>[]{target.type()}:是ProductFacadeServiceFeign接口。基于JDK动态代理的机制,创建一个实现ProductFacadeServiceFeign接口的动态代理对象。

handler:InvocationHandler实现类。针对ProductFacadeServiceFeign的proxy动态代理类,所有方法的调用,都经过InvocationHandler的invoke()方法拦截处理,由InvocationHandler.invoke()方法提供所有方法的实现逻辑。