一、读取注解信息

创新互联专注为客户提供全方位的互联网综合服务,包含不限于成都网站建设、成都网站制作、历城网络推广、重庆小程序开发、历城网络营销、历城企业策划、历城品牌公关、搜索引擎seo、人物专访、企业宣传片、企业代运营等,从售前售中售后,我们都将竭诚为您服务,您的肯定,是我们最大的嘉奖;创新互联为所有大学生创业者提供历城建站搭建服务,24小时服务热线:028-86922220,官方网址:www.cdcxhl.com
入口
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
public class CjsPriceServiceApplication {
  public static void main(String[] args) {
    SpringApplication.run(CjsPriceServiceApplication.class, args);
  }
}spring boot 项目启动后会自动扫描application上面的注解,@EnableFeignClients的注解如下
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(FeignClientsRegistrar.class)
public @interface EnableFeignClients {
。。。。
}在注解中导入了 FeignClientsRegistrar类,用来像spring注册,EnableFeignClients和FeignClient上面开发人员添加的注解信息
@Override
  public void registerBeanDefinitions(AnnotationMetadata metadata,
      BeanDefinitionRegistry registry) {
    registerDefaultConfiguration(metadata, registry);
    registerFeignClients(metadata, registry);
  }二、当项目启动,读取@Autowired时会调用,实现了FactoryBean接口的FeignClientFactoryBean.getObject()方法
   @Override
   public Object getObject() throws Exception {
     return getTarget();
   }
T getTarget() { FeignContext context = this.applicationContext.getBean(FeignContext.class); Feign.Builder builder = feign(context); if (!StringUtils.hasText(this.url)) { if (!this.name.startsWith("http")) { this.url = "http://" + this.name; } else { this.url = this.name; } this.url += cleanPath(); return (T) loadBalance(builder, context, new HardCodedTarget<>(this.type, this.name, this.url)); } if (StringUtils.hasText(this.url) && !this.url.startsWith("http")) { this.url = "http://" + this.url; } String url = this.url + cleanPath(); Client client = getOptional(context, Client.class); if (client != null) { if (client instanceof LoadBalancerFeignClient) { // not load balancing because we have a url, // but ribbon is on the classpath, so unwrap client = ((LoadBalancerFeignClient) client).getDelegate(); } builder.client(client); } Targeter targeter = get(context, Targeter.class); return (T) targeter.target(this, builder, context, new HardCodedTarget<>(this.type, this.name, url)); } 
可以看到 getTarget()有两种返回结果的情况,其原理都一样后来调用了 targeter.target()方法
package org.springframework.cloud.openfeign;
import feign.Feign;
import feign.Target;
/**
 * @author Spencer Gibb
 */
interface Targeter {
   T target(FeignClientFactoryBean factory, Feign.Builder feign,
      FeignContext context, Target.HardCodedTarget target);
}  默认实现类
package org.springframework.cloud.openfeign;
import feign.Feign;
import feign.Target;
/**
 * @author Spencer Gibb
 */
class DefaultTargeter implements Targeter {
  @Override
  public  T target(FeignClientFactoryBean factory, Feign.Builder feign,
      FeignContext context, Target.HardCodedTarget target) {
    return feign.target(target);
  }
}  然后再看 feign.target(target);方法
publicT target(Target target) { return build().newInstance(target); } public Feign build() { SynchronousMethodHandler.Factory synchronousMethodHandlerFactory = new SynchronousMethodHandler.Factory(client, retryer, requestInterceptors, logger, logLevel, decode404, closeAfterDecode, propagationPolicy); ParseHandlersByName handlersByName = new ParseHandlersByName(contract, options, encoder, decoder, queryMapEncoder, errorDecoder, synchronousMethodHandlerFactory); return new ReflectiveFeign(handlersByName, invocationHandlerFactory, queryMapEncoder); } } 
build()方法返回了创建代理类的对象,然后调用了创建代理的 newInstance方法
publicT newInstance(Target target) { 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)) { DefaultMethodHandler handler = new DefaultMethodHandler(method); defaultMethodHandlers.add(handler); methodToHandler.put(method, handler); } else { 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); for (DefaultMethodHandler defaultMethodHandler : defaultMethodHandlers) { defaultMethodHandler.bindTo(proxy); } return proxy; } 
最后,当我们项目中使用 @Autowired注入时,就回调用工厂类 FeignClientFactoryBean方法的 getObject()方法 返回我们的代理对象
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持创新互联。
网站题目:springcloudopenfeign源码实例解析
文章位置:http://www.scyingshan.cn/article/pcejje.html

 建站
建站
 咨询
咨询 售后
售后
 建站咨询
建站咨询 
 