成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

運(yùn)行時(shí)修改 Spring Boot 屬性的 N 種方式

開發(fā) 前端
application.properties文件是靜態(tài)的,應(yīng)用不重啟的情況下就無法更改。然而,Spring Boot ? ?提供了幾種強(qiáng)大的方法來在運(yùn)行時(shí)調(diào)整配置,而無需停機(jī)。無論是在實(shí)時(shí)應(yīng)用中功能切換,還是更改第三方相關(guān)配置都無需重啟應(yīng)用。

環(huán)境:Spring Boot3.2.5

1. 簡(jiǎn)介

在許多實(shí)際場(chǎng)景中,動(dòng)態(tài)管理應(yīng)用程序配置可能是一個(gè)關(guān)鍵需求。在微服務(wù)架構(gòu)中,由于某些操作,不同的服務(wù)可能需要實(shí)時(shí)配置更改。應(yīng)用可能需要根據(jù)用戶環(huán)境、外部API的數(shù)據(jù)或遵守動(dòng)態(tài)變化的要求來調(diào)整其行為。

application.properties文件是靜態(tài)的,應(yīng)用不重啟的情況下就無法更改。然而,Spring Boot    提供了幾種強(qiáng)大的方法來在運(yùn)行時(shí)調(diào)整配置,而無需停機(jī)。無論是在實(shí)時(shí)應(yīng)用中功能切換,還是更改第三方相關(guān)配置都無需重啟應(yīng)用。

本篇文章將介紹幾種在不直接修改application.properties文件的情況下,動(dòng)態(tài)更新 Spring Boot 應(yīng)用程序中屬性的策略。

2. 實(shí)戰(zhàn)案例

2.1 將Bean定義為Prototype作用域

當(dāng)我們需要在不影響已創(chuàng)建的 Bean 實(shí)例或不改變?nèi)謶?yīng)用程序狀態(tài)的情況下動(dòng)態(tài)調(diào)整特定 Bean 的屬性時(shí),直接注入帶有@Value 注解的 @Service類是不行的,因?yàn)檫@些屬性在應(yīng)用程序上下文的生命周期中是靜態(tài)的,簡(jiǎn)單說注入是一次性的。

我們可以使用@Configuration 配置類中的@Bean方法創(chuàng)建具有可修改屬性的 Bean。這種方法允許在應(yīng)用程序執(zhí)行過程中動(dòng)態(tài)更改屬性:

@Configuration
public class AppConfig {


  @Bean
  // 聲明為多例bean作用域
  @Scope("prototype")
  public UserService userService(@Value("${pack.app.title:}") String title) {
    return new UserService(title) ;
  }
}
public class UserService {
  private final String title;


  public UserService(String title) {
    this.title= title;
  }
  // getters, setters
}

通過@Scope將UserService作用域聲明為多例,這樣能保證每次通過getBean都拿到的是一個(gè)新的對(duì)象,既然是新對(duì)象那么每次都會(huì)重新注入title值。如下示例:

@RestController
public class UserController {
  @Resource
  private ApplicationContext context; 
  @Resource
  private ApplicationContext context ;
  @GetMapping("/update")
  public String update() {
    // 設(shè)置系統(tǒng)屬性值;
    // 注意你不能吧屬性定義在application.yml配置文件中
    System.setProperty("pack.app.title", "xxxooo - " + new Random().nextInt(10000)) ;
    return "update success" ;
  }
  @GetMapping("/title")
  public String title() {
    return this.context.getBean("us", UserService.class).getTitle() ;
  }
}

每次都是getBean獲取新對(duì)象,所以屬性title每次注入的都是最新的值。

2.2 使用@RefreshScope

我們可以使用 Spring Cloud 的@RefreshScope注解和/actuator/refresh端點(diǎn)。該接口會(huì)刷新所有@RefreshScopeBean,其實(shí)此種方式與上面2.1類似,首先是將bean對(duì)象生成代理,再通過代理對(duì)象執(zhí)行時(shí)每次都重新獲取getBean,以此來達(dá)到實(shí)時(shí)更新屬性。

引入依賴

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-context</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

開啟refresh接口

management:
  endpoint:
    refresh:
      enabled: true
  endpoints:
    web:
      exposure:
        include: refresh

如果你想在每次調(diào)用該接口時(shí)都記錄日志,進(jìn)行如下日志級(jí)別設(shè)置:

logging:
  level:
    org.springframework.boot.actuate: debug

以上配置完成后,接下來就可以定義需要實(shí)時(shí)刷新的bean對(duì)象了;

@RefreshScope
@Component
public class AppComponent {
  @Value("${pack.app.title:}")
  private String title ;


  public String getTitle() {
    return this.title ;
  }
}

接下來需要完成的是,動(dòng)態(tài)向Environment中添加PropertySource該對(duì)象中存入的是我們需要?jiǎng)討B(tài)刷新的值。

@Service
public class PackPropertyService {
  private static final String PACK_PROPERTIES_SOURCE_NAME = "packDynamicProperties" ;


  private final ConfigurableEnvironment environment ;
  public PackPropertyService(ConfigurableEnvironment environment) {
    this.environment = environment ;
  }
  // 更新或者添加PropertySource操作
  public void updateProperty(String key, String value) {
    MutablePropertySources propertySources = environment.getPropertySources() ;
    if (!propertySources.contains(PACK_PROPERTIES_SOURCE_NAME)) {
      Map<String, Object> properties = new HashMap<>() ;
      properties.put(key, value) ;
      propertySources.addFirst(new MapPropertySource(PACK_PROPERTIES_SOURCE_NAME, properties)) ;
    } else {
      // 替換更新值
      MapPropertySource propertySource = (MapPropertySource) propertySources.get(PACK_PROPERTIES_SOURCE_NAME) ;
      propertySource.getSource().put(key, value) ;
    }
  }
}

接下來寫一個(gè)接口進(jìn)行更新屬性值;

@RestController
@RequestMapping("/configprops")
public class PropertyController {
    
  private final PackPropertyService pps ;
  private final AppComponent app ;
  public PropertyController(PackPropertyService pps, AppComponent app) {
    this.pps = pps ;
    this.app = app ;
  }
    
  @PostMapping("/update")
  public String updateProperty(String key, String value) {
    pps.updateProperty(key, value) ;
    return "update success" ;
  }
  @GetMapping("/title")
  public String title() {
    return app.getTitle() ;
  }
}

首先調(diào)用/configprops/update接口更新屬性,接著調(diào)用 /actuator/refresh 接口進(jìn)行刷新操作,最后調(diào)用/configprops/title接口時(shí),AppComponent代理對(duì)象會(huì)會(huì)使用更新的配置屬性重新初始化 Bean。

2.3 使用外部配置文件

在某些情況下,有必要在應(yīng)用程序部署包之外管理配置更新,以確保對(duì)屬性進(jìn)行持續(xù)更改。這也允許我們將更改分發(fā)給多個(gè)應(yīng)用程序。

在本例中,我將使用與之前相同的 Spring Cloud 設(shè)置來啟用@RefreshScope和/actuator/refresh支持。我們使用外部文件external-config.properties。

我們還是借助上面的/configprops/title接口訪問屬性,通過 /actuator/refresh 接口屬性配置。

我們需要做的是在啟動(dòng)服務(wù)是添加如下啟動(dòng)參數(shù),指定外部配置文件

圖片圖片

初始文件內(nèi)容;

pack.app.title=xxxooo

圖片圖片

當(dāng)我們修改次文件內(nèi)容后,直接調(diào)用/actuator/refresh 接口;

圖片圖片

返回了已經(jīng)更新的配置屬性key,再次訪問/title接口;

圖片圖片

得到了最新的值。

責(zé)任編輯:武曉燕 來源: Spring全家桶實(shí)戰(zhàn)案例源碼
相關(guān)推薦

2015-07-20 15:44:46

Swift框架MJExtension反射

2020-09-28 15:54:18

Python語(yǔ)言技術(shù)

2024-03-21 09:15:58

JS運(yùn)行的JavaScrip

2020-12-07 13:31:43

GoMutex開發(fā)者

2019-07-12 09:30:12

DashboardDockerDNS

2021-09-11 15:38:23

容器運(yùn)行鏡像開放

2022-05-09 07:20:10

監(jiān)控項(xiàng)目工具

2023-08-21 09:37:57

MySQL工具MariaDB

2024-01-29 08:07:42

FlinkYARN架構(gòu)

2023-08-27 21:07:02

2013-11-26 16:49:55

Android開發(fā)運(yùn)行時(shí)KitKat

2021-08-18 08:32:09

代碼運(yùn)行時(shí)間示波器

2023-07-28 10:42:43

2023-01-03 09:10:21

2022-01-19 08:50:53

設(shè)備樹Linux文件系統(tǒng)

2024-03-20 10:46:00

云原生容器

2023-08-29 08:20:35

Kubernete跨云容器

2021-08-27 00:21:19

JSJust源碼

2023-02-12 12:00:57

2022-12-30 08:08:30

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 国产黄色网址在线观看 | 成年免费大片黄在线观看岛国 | 综合久久综合久久 | 欧美日韩免费在线 | 成人久草| 中文字幕一区二区三区在线乱码 | 日本精品视频一区二区三区四区 | 国产区在线视频 | 色接久久 | 亚洲毛片在线观看 | 亚洲性网 | 国产精品爱久久久久久久 | 国产欧美一区二区三区日本久久久 | 日本人麻豆 | 蜜桃毛片 | 国际精品鲁一鲁一区二区小说 | 视频1区 | 综合久| 亚洲一区在线日韩在线深爱 | 国产精品久久99 | 欧美日韩一区二区在线播放 | 美女操网站 | 成人精品一区二区三区中文字幕 | 国产视频精品在线观看 | 先锋资源吧 | 亚洲一区中文字幕 | 91精品国产高清久久久久久久久 | 欧美三级视频在线观看 | 免费美女网站 | 午夜影院免费体验区 | 国产精品178页 | 国产成人午夜精品影院游乐网 | 羞羞的视频在线观看 | av在线成人| 欧美专区日韩专区 | 欧美日韩在线观看一区二区三区 | 国产精品中文字幕在线播放 | 亚洲国产视频一区二区 | 国产yw851.c免费观看网站 | 成人在线精品视频 | 91原创视频 |