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

Spring應用中使用acutator/refresh刷新屬性不生效的問題分析及解決

 更新時間:2024年01月10日 11:43:28   作者:龍鶴鹿  
在Spring應用收到/actuator/refresh的POST請求后,標注了@RefreshScope以及@ConfiguratioinProperties的bean會被Spring容器重新加載,但是,在實際應用中,并沒有按照預期被Spring容器加載,本文將討論導致這種未按預期刷新的一種原因,感興趣的朋友可以參考下

問題的引入

在Spring應用收到/actuator/refresh的POST請求后,標注了@RefreshScope以及@ConfiguratioinProperties的bean會被Spring容器重新加載。這樣,如果配置文件(一般來自于配置中心,或者k8s的ConfigMap)發(fā)生了變化,那么這些變化就會因為Bean的重新加載而被應用感知。

但是,在實際應用中,可能會發(fā)現(xiàn)有些標注了@ConfigurationProperties的bean,并沒有按照預期被Spring容器加載。本文將討論導致這種未按預期刷新的一種原因。

結(jié)論

在進行詳細的討論之前,先把結(jié)論寫出來。如果大家時間緊張,而且碰巧遇到了這樣的問題,可以直接根據(jù)結(jié)論把問題解決掉。

確保標注了@ConfigurationProperties注解的bean沒有被任何Advisor依賴

比如:如下的Bean就不會被Spring容器刷新。

@ConfigurationProperties(prefix="com.dadaer.test")
public class MyProp {
  //...
}

// ............

@Component
public class MyAdvisor extends AbstractPointcutAdvisor {
   
   private final MyProp myProp;
   
   public class MyAdvisor(MyProp myProp) {
     this.myProp = myProp;
   }

  //...
}

這里的MyAdvisor依賴了MyProp,所以在收到/actuator/refresh的請求以后,MyProp的bean不會被重新加載。

分析

應用啟動階段

在Spring應用啟動時,在執(zhí)行到AbstractApplicationContext#refresh方法初始化容器的時候,其中有一個步驟(12大步中的第5步),Spring會向容器中注入所有的BeanPostProcessor,代碼如下:

// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);

而其中有一個BeanPostProcessor叫做:ConfigurationPropertiesBeans,是一個用來注冊所有標注了@ConfigurationProperties注解的后置處理器。

在初始化BeanPostProcessor的時候,會經(jīng)歷到下面的一段代碼:

@Override
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
    // TODO: Consider optimization by caching the list of the aspect names
    List<Advisor> candidateAdvisors = findCandidateAdvisors();
    for (Advisor advisor : candidateAdvisors) {
       if (advisor instanceof AspectJPointcutAdvisor pointcutAdvisor &&
             pointcutAdvisor.getAspectName().equals(beanName)) {
          return true;
       }
    }
    return super.shouldSkip(beanClass, beanName);
}

這里,會查找所有的Advisor并初始化。這樣,如果某個Advisor(比如上述MyAdvisor)依賴了一個@ConfigurationProperties注解的類(比如上述MyProp)。那么此時MyProp就需要在BeanPostProcessor之前初始化完成,即:MyProp先于ConfigurationPropertiesBeans完成初始化。

應用運行階段

在應用運行階段,當收到/actuator/refresh的POST請求時,會觸發(fā)RefreshEndpoint

@Endpoint(id = "refresh")
public class RefreshEndpoint {
    //...
    @WriteOperation
    public Collection<String> refresh() {
       Set<String> keys = this.contextRefresher.refresh();
       return keys;
    }
}

然后調(diào)用ContextRefresher#refresh方法進入下面的代碼:

public synchronized Set<String> refreshEnvironment() {
    Map<String, Object> before = extract(this.context.getEnvironment().getPropertySources());
    updateEnvironment();
    Set<String> keys = changes(before, extract(this.context.getEnvironment().getPropertySources())).keySet();
    this.context.publishEvent(new EnvironmentChangeEvent(this.context, keys));
    return keys;
}

這里,發(fā)送了一個EnvironmentChangeEvent事件,這個事件會被ConfigurationPropertiesRebinder捕獲,如下:

@Override
public void onApplicationEvent(EnvironmentChangeEvent event) {
    if (this.applicationContext.equals(event.getSource())
          // Backwards compatible
          || event.getKeys().equals(event.getSource())) {
       rebind();
    }
}

然后rebind方法被調(diào)用:

@ManagedOperation
public void rebind() {
    this.errors.clear();
    for (String name : this.beans.getBeanNames()) {
       rebind(name);
    }
}

這里beans變量的類型是:ConfigurationPropertiesBeans,它里面保存了所有待刷新的ConfigurationProperties的bean。

結(jié)論

因為啟動階段中,MyProp優(yōu)先于ConfigurationPropertiesBeans被加載,導致ConfigurationPropertiesBeans里面不會包含MyProp這個bean,從而導致它不會被刷新。

以上就是Spring應用中使用acutator/refresh刷新屬性不生效的問題分析及解決的詳細內(nèi)容,更多關(guān)于Spring使用acutator/refresh不生效的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • JAVA中的延遲隊列DelayQueue應用解析

    JAVA中的延遲隊列DelayQueue應用解析

    這篇文章主要介紹了JAVA中的延遲隊列DelayQueue應用解析,DelayQueue是一個根據(jù)元素的到期時間來排序的隊列,而并非是一般的隊列那樣先進先出,最快過期的元素排在隊首,越晚到期的元素排得越后,需要的朋友可以參考下
    2023-12-12
  • Java web.xml之contextConfigLocation作用案例詳解

    Java web.xml之contextConfigLocation作用案例詳解

    這篇文章主要介紹了Java web.xml之contextConfigLocation作用案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • Java獲取音頻文件的持續(xù)時間的實現(xiàn)方案

    Java獲取音頻文件的持續(xù)時間的實現(xiàn)方案

    在音視頻處理開發(fā)中,FFmpeg 一直是最常用的跨平臺音視頻處理工具,然而在很多實際場景中,FFmpeg 并不總是理想的選擇,本文將展示一種完全不依賴 FFprobe / FFmpeg 的方案,使用 Java 自帶的 javax.sound.sampled API 來獲取音頻文件的持續(xù)時間,需要的朋友可以參考下
    2025-11-11
  • Java重入鎖(ReentrantLock)從入門到源碼深度解析

    Java重入鎖(ReentrantLock)從入門到源碼深度解析

    本文給大家介紹Java重入鎖(ReentrantLock)從入門到源碼深度解析,通過本文學習可以全方位地認識ReentrantLock,從基本概念到高級特性,從使用方式到源碼剖析,從底層原理到實際應用,感興趣的朋友跟隨小編一起看看吧
    2026-02-02
  • 用Java設(shè)計模式中的觀察者模式開發(fā)微信公眾號的例子

    用Java設(shè)計模式中的觀察者模式開發(fā)微信公眾號的例子

    這篇文章主要介紹了用Java設(shè)計模式中的觀察者模式開發(fā)微信公眾號的例子,這里Java的微信SDK等部分便不再詳述,只注重關(guān)鍵部分和開發(fā)過程中觀察者模式優(yōu)點的體現(xiàn),需要的朋友可以參考下
    2016-02-02
  • Java中CopyOnWriteArrayList的使用解析

    Java中CopyOnWriteArrayList的使用解析

    這篇文章主要介紹了Java中CopyOnWriteArrayList的使用解析,CopyOnWriteArrayList適合使用在讀操作遠遠大于寫操作的場景里,比如緩存,它不存在擴容的概念,每次寫操作都要復制一個副本,在副本的基礎(chǔ)上修改后改變Array引用,需要的朋友可以參考下
    2023-12-12
  • 深入解析java中的locale

    深入解析java中的locale

    以下是對java中的locale進行了深入的分析介紹,需要的朋友可以過來參考下
    2013-08-08
  • Spring boot基于ScheduledFuture實現(xiàn)定時任務

    Spring boot基于ScheduledFuture實現(xiàn)定時任務

    這篇文章主要介紹了Spring boot基于ScheduledFuture實現(xiàn)定時任務,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-06-06
  • JAVA的Dubbo如何實現(xiàn)各種限流算法

    JAVA的Dubbo如何實現(xiàn)各種限流算法

    Dubbo是一種高性能的Java RPC框架,廣泛應用于分布式服務架構(gòu)中,在Dubbo中實現(xiàn)限流可以幫助服務在高并發(fā)場景下保持穩(wěn)定性和可靠性,常見的限流算法包括固定窗口算法、滑動窗口算法、令牌桶算法和漏桶算法,在Dubbo中集成限流器可以通過實現(xiàn)自定義過濾器來實現(xiàn)
    2025-01-01
  • Java Shutdown Hook場景使用及源碼分析

    Java Shutdown Hook場景使用及源碼分析

    shutdown hook 就是一個簡單的已初始化但是未啟動的線程,本文詳細的介紹了Java Shutdown Hook場景使用及源碼分析,感興趣的朋友可以參考一下
    2021-06-06

最新評論

普宁市| 邯郸市| 海丰县| 金溪县| 新和县| 赤壁市| 大宁县| 上栗县| 浦县| 微博| 禹州市| 湘潭市| 本溪| 茌平县| 会宁县| 霍邱县| 泰安市| 仁怀市| 北流市| 莒南县| 锡林浩特市| 喀什市| 中西区| 宜兰县| 湟中县| 衡东县| 鹰潭市| 屯门区| 沐川县| 乌拉特中旗| 霸州市| 墨竹工卡县| 新宁县| 安新县| 射洪县| 锦州市| 云浮市| 偏关县| 尤溪县| 崇礼县| 弋阳县|