欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

spring cloud openfeign 源碼實(shí)例解析

 更新時間:2019年10月15日 14:42:31   作者:挎木劍的游俠兒  
這篇文章主要介紹了spring cloud openfeign 源碼實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下

一、讀取注解信息

入口

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 {
。。。。
}

在注解中導(dǎo)入了 FeignClientsRegistrar類,用來像spring注冊,EnableFeignClients和FeignClient上面開發(fā)人員添加的注解信息

@Override
  public void registerBeanDefinitions(AnnotationMetadata metadata,
      BeanDefinitionRegistry registry) {
    registerDefaultConfiguration(metadata, registry);
    registerFeignClients(metadata, registry);
  }

二、當(dāng)項目啟動,讀取@Autowired時會調(diào)用,實(shí)現(xiàn)了FactoryBean接口的FeignClientFactoryBean.getObject()方法

   @Override
   public Object getObject() throws Exception {
     return getTarget();
   }
<T> 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()有兩種返回結(jié)果的情況,其原理都一樣后來調(diào)用了 targeter.target()方法

package org.springframework.cloud.openfeign;

import feign.Feign;
import feign.Target;

/**
 * @author Spencer Gibb
 */
interface Targeter {

  <T> T target(FeignClientFactoryBean factory, Feign.Builder feign,
      FeignContext context, Target.HardCodedTarget<T> target);

}

默認(rèn)實(shí)現(xiàn)類

package org.springframework.cloud.openfeign;

import feign.Feign;
import feign.Target;

/**
 * @author Spencer Gibb
 */
class DefaultTargeter implements Targeter {

  @Override
  public <T> T target(FeignClientFactoryBean factory, Feign.Builder feign,
      FeignContext context, Target.HardCodedTarget<T> target) {
    return feign.target(target);
  }

}

然后再看 feign.target(target);方法

public <T> T target(Target<T> 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()方法返回了創(chuàng)建代理類的對象,然后調(diào)用了創(chuàng)建代理的 newInstance方法

public <T> T newInstance(Target<T> target) {
  Map<String, MethodHandler> nameToHandler = targetToHandlersByName.apply(target);
  Map<Method, MethodHandler> methodToHandler = new LinkedHashMap<Method, MethodHandler>();
  List<DefaultMethodHandler> defaultMethodHandlers = new LinkedList<DefaultMethodHandler>();

  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;
 }

最后,當(dāng)我們項目中使用 @Autowired注入時,就回調(diào)用工廠類 FeignClientFactoryBean方法的 getObject()方法 返回我們的代理對象

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java catch與throw同時使用的操作

    Java catch與throw同時使用的操作

    這篇文章主要介紹了Java catch與throw同時使用的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • Springboot使用Maven占位符@替換不生效問題及解決

    Springboot使用Maven占位符@替換不生效問題及解決

    這篇文章主要介紹了Springboot使用Maven占位符@替換不生效問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • Spring通過@Lazy解決構(gòu)造方法形式的循環(huán)依賴問題

    Spring通過@Lazy解決構(gòu)造方法形式的循環(huán)依賴問題

    這篇文章主要給大家介紹了Spring如何通過@Lazy解決構(gòu)造方法形式的循環(huán)依賴問題,文中有詳細(xì)的代碼示例,對大家的學(xué)習(xí)活工作有一定的幫助,具有一定的參考價值,需要的朋友可以參考下
    2023-10-10
  • java 創(chuàng)建自定義數(shù)組

    java 創(chuàng)建自定義數(shù)組

    本篇文章是關(guān)于java 如何自己創(chuàng)建自定義數(shù)組,這里給大家一個小實(shí)例,希望能幫助有所需要的同學(xué)
    2016-07-07
  • Spring activiti如何實(shí)現(xiàn)指定任務(wù)處理者

    Spring activiti如何實(shí)現(xiàn)指定任務(wù)處理者

    這篇文章主要介紹了Spring activiti如何實(shí)現(xiàn)指定任務(wù)處理者,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-11-11
  • SpringBoot2 JPA解決懶加載異常的問題

    SpringBoot2 JPA解決懶加載異常的問題

    這篇文章主要介紹了SpringBoot2 JPA解決懶加載異常的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • Java編程中的檢查型異常與非檢查型異常分析

    Java編程中的檢查型異常與非檢查型異常分析

    這篇文章主要介紹了Java編程中的未檢查型異常與非檢查型異常,以及異常的處理方式,需要的朋友可以參考下
    2017-09-09
  • 擴(kuò)展tk.mybatis的流式查詢功能實(shí)現(xiàn)

    擴(kuò)展tk.mybatis的流式查詢功能實(shí)現(xiàn)

    mybatis查詢默認(rèn)是一次獲取全部,如果數(shù)據(jù)過于龐大,就會導(dǎo)致OOM問題,本文就介紹了tk.mybatis 流式查詢,具有一定的參考價值,感興趣的可以了解一下
    2021-12-12
  • SpringBoot?HikariCP連接池詳解

    SpringBoot?HikariCP連接池詳解

    這篇文章主要介紹了SpringBoot2.0?中?HikariCP?數(shù)據(jù)庫連接池原理解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • 五分鐘手?jǐn)]一個Spring容器(萌芽版)

    五分鐘手?jǐn)]一個Spring容器(萌芽版)

    Spring的兩大內(nèi)核分別是IOC和AOP,其中最最核心的是IOC。這篇文章主要介紹了五分鐘,手?jǐn)]一個Spring容器的相關(guān)知識,需要的朋友可以參考下
    2022-03-03

最新評論