最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

spring?NamedContextFactory在Fegin配置及使用詳解

 更新時間:2023年11月06日 14:06:29   作者:頭飾?tiger1000  
在我們日常項目中,使用FeignClient實現(xiàn)各系統(tǒng)接口調用變得更加簡單,?在各個系統(tǒng)集成過程中,難免會遇到某些系統(tǒng)的Client需要特殊的配置、返回讀取等需求。Feign使用NamedContextFactory來為每個Client模塊構造單獨的上下文(ApplicationContext)

引言

文中代碼來源于spring-cloud的2.2.9.release版本。

1、NamedContextFactory

看一下NamedContextFactory的主要代碼。NamedContextFactory中有個contexts屬性,contexts是Map<String, AnnotationConfigApplicationContext>,這個map以name為key 以子上線文為value。

getContext方法會從contexts查找name為key的子上下文,如果沒有的話會調用createContext創(chuàng)建一個子上下文。
createContext方法是NamedContextFactory的重要方法之一。

createContext首選創(chuàng)建一個AnnotationConfigApplicationContext作為子上下文;然后查詢configurations中有無以此name為key的Specification(這個類稍后介紹),如果有相關的Specification的話就會注冊這個
Specification存儲的class到子上下文;

然后注冊configurations中包含的以"defalut."開頭的key的Specification中存儲的class到子上下文;緊接著在子上下文注冊了PropertyPlaceholderAutoConfiguration 和 defaultConfigType(構造方法中初始的變量);

緊接著注冊了一個名字為propertySourceName的MapPropertySource,MapPropertySource的內容包括一個key為propertyName值為name的變量;后邊進行設置parent然后refresh子上下文。

可以看到NamedContextFactory可以通過getContext(name)并為每個模塊構造不同的上下文,并且加載相關的配置加載到子上下文。

使用時可以通過Specification就是存儲了模塊名稱和每個模塊的配置類,進行配置,也可以通過NamedContextFactory指定一個配置類。

后邊的getInstance等方法,都是通過查詢子上下文中的來加載bean。

public abstract class NamedContextFactory<C extends NamedContextFactory.Specification>
        implements DisposableBean, ApplicationContextAware {
   private final String propertySourceName;
   private final String propertyName;
private Map<String, AnnotationConfigApplicationContext> contexts = new ConcurrentHashMap<>();
private Map<String, C> configurations = new ConcurrentHashMap<>();
private Class<?> defaultConfigType;
public NamedContextFactory(Class<?> defaultConfigType, String propertySourceName,
            String propertyName) {
        this.defaultConfigType = defaultConfigType;
        this.propertySourceName = propertySourceName;
        this.propertyName = propertyName;
    }
  protected AnnotationConfigApplicationContext getContext(String name) {
        if (!this.contexts.containsKey(name)) {
            synchronized (this.contexts) {
                if (!this.contexts.containsKey(name)) {
                    this.contexts.put(name, createContext(name));
                }
            }
        }
        return this.contexts.get(name);
    }
    protected AnnotationConfigApplicationContext createContext(String name) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        if (this.configurations.containsKey(name)) {
            for (Class<?> configuration : this.configurations.get(name)
                    .getConfiguration()) {
                context.register(configuration);
            }
        }
        for (Map.Entry<String, C> entry : this.configurations.entrySet()) {
            if (entry.getKey().startsWith("default.")) {
                for (Class<?> configuration : entry.getValue().getConfiguration()) {
                    context.register(configuration);
                }
            }
        }
        context.register(PropertyPlaceholderAutoConfiguration.class,
                this.defaultConfigType);
        context.getEnvironment().getPropertySources().addFirst(new MapPropertySource(
                this.propertySourceName,
                Collections.<String, Object>singletonMap(this.propertyName, name)));
        if (this.parent != null) {
            // Uses Environment from parent as well as beans
            context.setParent(this.parent);
            // jdk11 issue
            // https://github.com/spring-cloud/spring-cloud-netflix/issues/3101
            context.setClassLoader(this.parent.getClassLoader());
        }
        context.setDisplayName(generateDisplayName(name));
        context.refresh();
        return context;
    }
public <T> T getInstance(String name, Class<T> type) {
        AnnotationConfigApplicationContext context = getContext(name);
        try {
            return context.getBean(type);
        }
        catch (NoSuchBeanDefinitionException e) {
            // ignore
        }
        return null;
    }
public void setConfigurations(List<C> configurations) {
        for (C client : configurations) {
            this.configurations.put(client.getName(), client);
        }
    }
}
public interface Specification {
        String getName();
        Class<?>[] getConfiguration();
    }

2、NamedContextFactory在feign中使用

feign中提供了Specification的實現(xiàn)

class FeignClientSpecification implements NamedContextFactory.Specification {
    private String name;
    private Class<?>[] configuration;
}

EnableFeignClients中import了FeignClientsRegistrar,下面代碼不是全部的EnableFeignClients代碼,做了簡化處理。

@Import(FeignClientsRegistrar.class)
public @interface EnableFeignClients中import了 {
Class&lt;?&gt;[] defaultConfiguration() default {};
}

具體client的配置注冊是在FeignClientsRegistrar 實現(xiàn)的。registerBeanDefinitions方法實現(xiàn)了具體注冊。

registerDefaultConfiguration 將EnableFeignClients中的defaultConfiguration的配置,以"defalut."開頭的名稱注入到了容器。

registerFeignClients掃描所有的@FeignClient類,得到name(具體邏輯可參考源碼),得到FeignClient的configration屬性,再調用registerClientConfiguration 就行配置(注冊了name + "." + FeignClientSpecification.class.getSimpleName()的bean)。

class FeignClientsRegistrar
        implements ImportBeanDefinitionRegistrar, ResourceLoaderAware, EnvironmentAware {
 
    @Override
    public void registerBeanDefinitions(AnnotationMetadata metadata,
            BeanDefinitionRegistry registry) {
        registerDefaultConfiguration(metadata, registry);
        registerFeignClients(metadata, registry);
    }

    private void registerClientConfiguration(BeanDefinitionRegistry registry, Object name,
            Object configuration) {
        BeanDefinitionBuilder builder = BeanDefinitionBuilder
                .genericBeanDefinition(FeignClientSpecification.class);
        builder.addConstructorArgValue(name);
        builder.addConstructorArgValue(configuration);
        registry.registerBeanDefinition(
                name + "." + FeignClientSpecification.class.getSimpleName(),
                builder.getBeanDefinition());
    }
}

在FeignAutoConfiguration中引入了所有的 FeignClientSpecification,并且初始化了FeiginContext,調用了setConfigurations(參考NamedContextFactory方法,此操作將以name為key,F(xiàn)eignClientSpecification對象為value添加到NamedContextFactory的configurations屬性中),后續(xù)在調用到NamedContextFactory的createContext方法時,會將configurations屬性中的配置進行加載。

public class FeignAutoConfiguration {
    @Autowired(required = false)
private List<FeignClientSpecification> configurations = new ArrayList<>();
@Bean
public FeignContext feignContext() {
    FeignContext context = new FeignContext();
    context.setConfigurations(this.configurations);
    return context;
    }
}

以上就是spring NamedContextFactory在Fegin配置及使用詳解的詳細內容,更多關于spring NamedContextFactory Fegin配置的資料請關注腳本之家其它相關文章!

相關文章

  • Java內存泄漏問題的排查、優(yōu)化與最佳實踐

    Java內存泄漏問題的排查、優(yōu)化與最佳實踐

    在?Java?開發(fā)中,內存泄漏是一個常見且令人頭疼的問題,內存泄漏指的是程序在運行過程中,已經不再使用的對象沒有被及時釋放,從而導致內存占用不斷增加,最終可能導致程序崩潰或性能顯著下降,本文給大家介紹了Java內存泄漏排查、優(yōu)化與最佳實踐
    2025-01-01
  • Spring Boot 動態(tài)數(shù)據(jù)源示例(多數(shù)據(jù)源自動切換)

    Spring Boot 動態(tài)數(shù)據(jù)源示例(多數(shù)據(jù)源自動切換)

    本篇文章主要介紹了Spring Boot 動態(tài)數(shù)據(jù)源示例(多數(shù)據(jù)源自動切換),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-02-02
  • 使用Spring底層組件實現(xiàn)Aware接口

    使用Spring底層組件實現(xiàn)Aware接口

    這篇文章主要介紹了使用Spring底層組件實現(xiàn)Aware接口,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-07-07
  • Spring cloud config 配置文件加密方式

    Spring cloud config 配置文件加密方式

    這篇文章給大家介紹了Spring cloud config 配置文件加密方式,非常不錯,具有一定的參考借鑒價值,感興趣的朋友跟隨腳步之家小編一起學習吧
    2018-05-05
  • Java中this關鍵字的4種用法詳解(附常見面試題)

    Java中this關鍵字的4種用法詳解(附常見面試題)

    在Java的編程世界里,this關鍵字宛如一把神奇的鑰匙,看似簡單,卻蘊含著強大的功能,這篇文章主要介紹了Java中this關鍵字的4種用法的相關資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2025-06-06
  • JMeter中Java Request采樣器的使用指南

    JMeter中Java Request采樣器的使用指南

    Apache JMeter 是一款功能強大的性能測試工具,支持多種協(xié)議和測試場景,JMeter還允許通過 Java Request采樣器 調用自定義的Java代碼,本文將詳細介紹如何在JMeter中使用Java Request采樣器,需要的朋友可以參考下
    2025-02-02
  • Java狀態(tài)設計模式實現(xiàn)對象狀態(tài)轉換的優(yōu)雅方式

    Java狀態(tài)設計模式實現(xiàn)對象狀態(tài)轉換的優(yōu)雅方式

    Java狀態(tài)設計模式通過將對象的行為和狀態(tài)分離,使對象能夠根據(jù)不同的狀態(tài)進行不同的行為操作。它通過將狀態(tài)抽象成一個獨立的類來實現(xiàn)對狀態(tài)的封裝,從而簡化了復雜的條件判斷和狀態(tài)轉換
    2023-04-04
  • java?-jar指定spring配置文件完整示例

    java?-jar指定spring配置文件完整示例

    這篇文章主要介紹了java?-jar指定spring配置文件的相關資料,通過示例講解了激活dev profile、設置外部配置路徑、直接指定配置文件名,需要的朋友可以參考下
    2025-06-06
  • IDEA代碼規(guī)范插件P3C+代碼注釋模板配置方法

    IDEA代碼規(guī)范插件P3C+代碼注釋模板配置方法

    這篇文章主要介紹了IDEA代碼規(guī)范插件P3C+代碼注釋模板配置方法,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-01-01
  • Java語言實現(xiàn)簡單FTP軟件 FTP上傳下載管理模塊實現(xiàn)(11)

    Java語言實現(xiàn)簡單FTP軟件 FTP上傳下載管理模塊實現(xiàn)(11)

    這篇文章主要為大家詳細介紹了Java語言實現(xiàn)簡單FTP軟件,F(xiàn)TP本地文件管理模塊的實現(xiàn)方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-04-04

最新評論

宝清县| 杭锦后旗| 鄂州市| 阳春市| 六枝特区| 山西省| 桂平市| 永修县| 齐齐哈尔市| 且末县| 仙桃市| 阳城县| 衡东县| 金寨县| 聂拉木县| 治县。| 阿瓦提县| 衡阳县| 青川县| 泌阳县| 西乌| 景德镇市| 康平县| 南陵县| 镇康县| 景洪市| 康马县| 大同县| 卓资县| 农安县| 玉田县| 科技| 高雄市| 北京市| 云林县| 博野县| 阿合奇县| 高陵县| 双柏县| 广昌县| 鄂尔多斯市|