SpringCloud微服务项目之间调用是通过httprest请求来进行服务调用的,之前我们会用到HttpClient等工具来进行服务请求,Spring对这种请求进行了处理,封装成了可声明式的web客户端,使得编写web客户端更容易,feign还支持可插拔的编码器和解码器,Spring在用的时候增加了对@requestMapping的处理,同时,SpringCloud还对feign集成了注册中心(eureka)和客户端负载均衡(ribbon),了解springcloud架构可以加求求:三五三六二四七二五九,使得我们拥有一个客户端负载均衡的web请求客户端。
Feign源码分析
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 扫描本项目里面的java文件,把bean对象封装成BeanDefinitiaon对象,然后调用DefaultListableBeanFactory#registerBeanDefinition()方法把beanName放到DefaultListableBeanFactory 的 List beanDefinitionNames 中去
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
postProcessBeanFactory(beanFactory);
// 在这里调用到FeignClientsRegistrar对象的registerBeanDefinitions()方法
invokeBeanFactoryPostProcessors(beanFactory);
//从DefaultListableBeanFactory里面的beanDefinitionNames中找到所有实现了BeanPostProcessor接口的方法,如果有排序进行排序后放到list中
registerBeanPostProcessors(beanFactory);
//Spring的国际化
initMessageSource();
//
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
//
registerListeners();
// Spring的IOC、ID处理。Spring的AOP。事务都是在IOC完成之后调用了BeanPostProcessor#postProcessBeforeInitialization()和postProcessBeforeInitialization()方法,AOP(事务)就是在这里处理的
finishBeanFactoryInitialization(beanFactory);
// 执行完之后调用实现了所有LifecycleProcessor接口的类的onRefresh()方法,同时调用所有观察了ApplicationEvent接口的事件(观察者模式)
finishRefresh();
}
catch (BeansException ex) {
// 找到所有实现了DisposableBean接口的方法,调用了destroy()方法,这就是bean的销毁
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
throw ex;
}
finally {
resetCommonCaches();
}
}
} 根据上面整理的代码发现,FeignClientsRegistrar#registerBeanDefinitions()方法是在扫描完bean之后,只放了一个beanname的情况下, 并没有进行IOC注册的时候调用的,这就是Spring动态扩展Bean,实现BeanDefinitionRegistryPostProcessor接口的所有方法也会在这里调用下postProcessBeanDefinitionRegistry()方法。关于Spring的东西就分析到这里。下面回到正题,分析FeignClientsRegistrar#registerBeanDefinitions()方法:
@Override
public void registerBeanDefinitions(Annotationmetadata metadata,
BeanDefinitionRegistry registry) {
registerDefaultConfiguration(metadata, registry);//扫描EnableFeignClients标签里配置的信息,注册到beanDefinitionNames中。
registerFeignClients(metadata, registry);
}
public void registerFeignClients(Annotationmetadata metadata,
BeanDefinitionRegistry registry) {
AnnotationTypeFilter annotationTypeFilter = new AnnotationTypeFilter(
FeignClient.class);
//省略代码...根据EnableFeignClients配置的basePackages找到包下所有FeignClient注解的类,Spring的Commponet也是这么干的
for (String basePackage : basePackages) {
Set candidateComponents = scanner
.findCandidateComponents(basePackage);
for (BeanDefinition candidateComponent : candidateComponents) {
if (candidateComponent instanceof AnnotatedBeanDefinition) {
// verify annotated class is an interface
AnnotatedBeanDefinition beanDefinition = (AnnotatedBeanDefinition) candidateComponent;
Annotationmetadata annotationmetadata = beanDefinition.getmetadata();
Assert.isTrue(annotationmetadata.isInterface(),
"@FeignClient can only be specified on an interface");
Map attributes = annotationmetadata
.getAnnotationAttributes(
FeignClient.class.getCanonicalName());
String name = getClientName(attributes);
//这个方法就是在ioc容器中塞入一个FeignClientSpecification对象,从而构建FeignContext子容器。
registerClientConfiguration(registry, name,
attributes.get("configuration"));
//重点分析这个
registerFeignClient(registry, annotationmetadata, attributes);
}
}
}
}
private void registerFeignClient(BeanDefinitionRegistry registry,
Annotationmetadata annotationmetadata, Map attributes) {
String className = annotationmetadata.getClassName();
BeanDefinitionBuilder definition = BeanDefinitionBuilder
.genericBeanDefinition(FeignClientFactoryBean.class);//对FeignClientFactoryBean对象生成一个BeanDefinition对象
...读取配置
String alias = name + "FeignClient";
AbstractBeanDefinition beanDefinition = definition.getBeanDefinition();
boolean primary = (Boolean)attributes.get("primary"); // has a default, won't be null
beanDefinition.setPrimary(primary);
String qualifier = getQualifier(attributes);
if (StringUtils.hasText(qualifier)) {
alias = qualifier;
}
BeanDefinitionHolder holder = new BeanDefinitionHolder(beanDefinition, className,
new String[] { alias });
//注册到beanDefinitionNames中对象
BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);//
} 首先看配置了url的,指定了url的feignclient解析,一直跟着代码跟到了Feign.Builder#target()方法:
publicT target(Target target) { return build().newInstance(target); } public Feign build() { SynchronousMethodHandler.Factory synchronousMethodHandlerFactory = new SynchronousMethodHandler.Factory(client, retryer, requestInterceptors, logger, logLevel, decode404); ParseHandlersByName handlersByName = new ParseHandlersByName(contract, options, encoder, decoder, errorDecoder, synchronousMethodHandlerFactory); return new ReflectiveFeign(handlersByName, invocationHandlerFactory); }
直接看ReflectiveFeign#newInstance()方法:
//ReflectiveFeign#newInstance() publicT newInstance(Target target) { //动态代理的handler类目前穿进来的是ParseHandlersByName类,所以这里要看ParseHandlersByName#apply()直接看下一个方法 Map nameToHandler = targetToHandlersByName.apply(target); Map methodToHandler = new linkedHashMap (); List defaultMethodHandlers = new linkedList (); for (Method method : target.type().getMethods()) { if (method.getDeclaringClass() == Object.class) { continue; } else if(Util.isDefault(method)) {//默认方法会走到这里,比如toString(),hashCode()等方法 DefaultMethodHandler handler = new DefaultMethodHandler(method); defaultMethodHandlers.add(handler); methodToHandler.put(method, handler); } else {//这里才是装配的调用类,上文分析到计息的handler是SynchronousMethodHandler#invoke() methodToHandler.put(method, nameToHandler.get(Feign.configKey(target.type(), method))); } } InvocationHandler handler = factory.create(target, methodToHandler); T proxy = (T) Proxy.newProxyInstance(target.type().getClassLoader(), new Class>[]{target.type()}, handler);//jdk动态代理 for(DefaultMethodHandler defaultMethodHandler : defaultMethodHandlers) { defaultMethodHandler.bindTo(proxy); } return proxy; } //ParseHandlersByName#apply类,构建动态代理的handler public Map apply(Target key) { List metadata = contract.parseAndValidatatemetadata(key.type()); Map result = new linkedHashMap (); for (Methodmetadata md : metadata) { BuildTemplateByResolvingArgs buildTemplate; if (!md.formParams().isEmpty() && md.template().bodyTemplate() == null) { buildTemplate = new BuildFormEncodedTemplateFromArgs(md, encoder);//通过自定义的encoder去解析参数 } else if (md.bodyIndex() != null) { buildTemplate = new BuildEncodedTemplateFromArgs(md, encoder);//通过自定义的encoder去解析参数 } else { buildTemplate = new BuildTemplateByResolvingArgs(md); } //创建handler,再看Factory#create()方法,下一个方法 result.put(md.configKey(), factory.create(key, md, buildTemplate, options, decoder, errorDecoder)); } return result; } //Factory#create(),构建一个SynchronousMethodHandler去处理请求,调用invoke方法 public MethodHandler create(Target> target, Methodmetadata md, RequestTemplate.Factory buildTemplateFromArgs, Options options, Decoder decoder, ErrorDecoder errorDecoder) { return new SynchronousMethodHandler(target, client, retryer, requestInterceptors, logger, logLevel, md, buildTemplateFromArgs, options, decoder, errorDecoder, decode404); } //SynchronousMethodHandler#invoke()方法:实际调用的方法 //@Override public Object invoke(Object[] argv) throws Throwable { RequestTemplate template = buildTemplateFromArgs.create(argv);//构建requestTemplate对象 Retryer retryer = this.retryer.clone(); while (true) { try { return executeAndDecode(template);//下面不分析了,就是执行execute方法并且解码饭后返回值 } catch (RetryableException e) { retryer.continueOrPropagate(e); if (logLevel != Logger.Level.NONE) { logger.logRetry(metadata.configKey(), logLevel); } continue; } } }



