在運行時交換出Spring Bean配置

如今,大多數Java開發人員都定期與Spring打交道,而我們當中的許多人已經熟悉了Spring的功能和局限性。

最近,我遇到了一個我從未遇到過的問題:引入了基于運行時引入的配置來重新連接Bean內部的功能。 這對于簡單的配置更改或交換掉諸如StrategyFactory類之類的東西非常有價值,而不是重建應用程序上下文的復雜部分。

我能夠找到一些有關如何執行此操作的注釋,但是我認為有些人可能會發現我的注釋和代碼示例很有用,特別是因為我可以確認該技術在Spring 1.2.6之前的版本中可以使用。 不幸的是,并不是我們所有人都有幸成為每個圖書館中最新最好的圖書館。

問題范圍

我將概述的方法主要是針對單個bean的更改,盡管可以輕松擴展此代碼以更改多個bean。 可以通過JMX或向管理員公開的其他UI調用它。

它沒有涉及的一件事是在整個應用程序中重新布線單例–可以想到,這可以通過對當前應用程序上下文的某種反射和檢查來完成,但是在大多數應用程序中,除非它們具有某種臨時關閉或關閉的方式,否則可能不安全。在整個應用程序中進行更改時,將一段時間內的所有處理都阻塞。

編碼

這是示例代碼。 它將獲取一個包含bean定義的字符串列表,并將它們連接到新的臨時Spring上下文中。 您將看到可以提供父上下文,這在您的新bean定義需要引用應用程序中已經配置的bean時很有用。

public static <T> Map<String, T> extractBeans(Class<T> beanType,List<String> contextXmls, ApplicationContext parentContext) throws Exception {List<String> paths = new ArrayList<String>();try {for (String xml : contextXmls) {File file = File.createTempFile("spring", "xml");// ... write the file using a utility methodFileUtils.writeStringToFile(file, xml, "UTF-8");paths.add(file.getAbsolutePath());}String[] pathArray = paths.toArray(new String[0]);return buildContextAndGetBeans(beanType, pathArray, parentContext);} finally {// ... clean up temp files immediately if desired}
}private static <T> Map<String, T> buildContextAndGetBeans(Class<T> beanType,String[] paths, ApplicationContext parentContext) throws Exception {FileSystemXmlApplicationContext context =new FileSystemXmlApplicationContext(paths, false, parentContext) {@Override  // suppress refresh events bubbling to parent contextpublic void publishEvent(ApplicationEvent event) { }};try {// avoid classloader errors in some environmentscontext.setClassLoader(beanType.getClassLoader());context.refresh(); // parse and load contextMap<String, T> beanMap = context.getBeansOfType(beanType);return beanMap;} finally {try {context.close();} catch (Exception e) {// ... log this}}
}

如果查看buildContextAndGetBeans() ,您將看到它通過使用提供的XML bean定義文件構建Spring上下文來完成大部分工作。 然后,它返回所請求類型的構造bean的映射。

注意:由于臨時Spring上下文已被破壞,因此請確保您的bean沒有生命周期方法,該方法會導致它們在停止或破壞時處于無效狀態。

這是一個Spring上下文的示例,可用于重新連接組件。 想象一下,我們有一個電子商務系統,可以進行欺詐檢查,但是可以使用多種策略來檢查欺詐。 我們可能希望從服務類中交換這些內??容,而不必停止并重新配置應用程序,因為這樣做會造成業務損失。 也許我們正在發現對該系統的特定濫用,可以通過更改用于定位欺詐性訂單的策略來更好地解決。

這是一個示例XML定義,可用于重新連接我們的FraudService

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans><bean id="fraudStrategy" class="com.example.SomeFraudStategory"><!-- example of a bean defined in the parent application context that we can reference --><property name="fraudRuleFactory" ref="fraudRuleFactory"/></bean>
</beans>

這是您可以使用對定義的欺詐策略的引用來重新連接Bean的代碼,假設您已將其包含在名為SpringUtils的實用工具類中:

public class FraudService implements ApplicationContextAware {private ApplicationContext context;// volatile for thread safety (in Java 1.5 and up only)private volatile FraudStrategy fraudStrategy;@Override // get a handle on the the parent contextpublic void setApplicationContext(ApplicationContext context) {this.context = context;}public void swapFraudStategy(String xmlDefinition) throws Exception {List<Sting> definitions = Arrays.asList(xmlDefinition);Map<String, FraudStrategy> beans =SpringUtils.extractBeans(FraudStrategy.class, definitions, context);if (beans.size() != 1) {throw new RuntimeException("Invalid number of beans: " + beans .size());}this.fraudStrategy = beans.values().iterator().next();}}

在那里,您擁有了! 可以適當地擴展此示例以滿足您的需求,但是我認為它展示了如何動態創建Spring上下文并使用其bean重新配置應用程序而無需停機的基礎知識。

參考:在Carfey Software博客上 ,我們的JCG合作伙伴提供了在運行時交換Spring Bean配置的信息 。

相關文章 :
  • 零XML的Spring配置
  • Spring依賴注入技術的發展
  • Spring MVC3 Hibernate CRUD示例應用程序
  • 使用Spring AOP進行面向方面的編程
  • Spring MVC開發–快速教程

翻譯自: https://www.javacodegeeks.com/2011/09/swapping-out-spring-bean-configuration.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/374314.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/374314.shtml
英文地址,請注明出處:http://en.pswp.cn/news/374314.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Proximal Algorithms--Accelerated proximal gradient method

4.3 Accelerated proximal gradient method&#xff1a; 加速近端梯度方法&#xff1a; 基本的近端梯度方法的所謂的“加速”版本&#xff0c;就是在算法中包含了一個外推(extrapolation)步驟&#xff0c;一個簡單的版本是&#xff1a; yk1:xkωk(xk?xk?1)xk1:proxλkg(yk1?…

C語言代碼規范(七)#define

#define 宏定義的使用 #define MAX(x, y) ( ((x) > (y)) ? (x) : (y) ) #define MIN(x, y) ( ((x) < (y)) ? (x) : (y) ) 在宏定義中要把參數用括號擴起來( ((x) > (y)) ? (x) : (y) )。 因為宏只是簡單的文本替換&#xff0c;如果不注意&#xff0c;很容…

http 二進制_淺談HTTP協議

HTTP一、HTTP協議http協議&#xff0c;是超文本傳輸協議&#xff0c;此協議是基于TCP/IP的協議&#xff0c;是互聯網上應用最為廣泛的一直網絡協議是一種無狀態協議&#xff0c;默認端口為80,。設計HTTP的最初目的是為了提供一種發布和接受HTML頁面的方法。通過HTTP或者HTTPS協…

登陸注冊

登陸注冊&#xff0c;注冊的賬號存在服務器的數據庫里&#xff0c;成功了就給你返回成功&#xff0c;失敗了就返回失敗 有三種登陸方式&#xff1a;普通注冊&#xff0c;手機號注冊&#xff0c;第三方注冊轉載于:https://www.cnblogs.com/SensenCoder/p/4885606.html

Java并發教程–線程池

Java 1.5中提供的最通用的并發增強功能之一是引入了可自定義的線程池。 這些線程池使您可以對諸如線程數&#xff0c;線程重用&#xff0c;調度和線程構造之類的東西進行大量控制。 讓我們回顧一下。 首先&#xff0c;線程池。 讓我們直接進入java.util.concurrent.ExecutorSer…

HTTPPost/AFNetWorking/JSONModel/NSPredicate

一、HTTPPost 1. POST方式發送請求 HTTP協議下默認數據發送請求方法是GET方式&#xff0c;若需要使用POST方法&#xff0c;則需要對發送的請求也就是request對象&#xff0c;進行屬性設置。 步驟如下&#xff1a; > 要發送的請求對象&#xff0c;需要使用可變請求對象 [[NSM…

C語言代碼規范(八)使用const修飾值不允許改變的變量

使用const限定一個變量的值不允許被改變&#xff0c;從而保護被修飾的東西&#xff0c;防止意外&#xff0c;提高程序的可靠性和安全性。

教育小思

父母的時代是“攢錢&#xff0c;買房&#xff0c;生子&#xff0c;終老”&#xff0c;而現在的時代是“教育&#xff0c;創造&#xff0c;傳承&#xff0c;成長”。 改變世界&#xff0c;從教育起步。 傳統教育的不足之處&#xff1a; 1. 學習體驗不佳&#xff0c;學習者被迫…

linux redis客戶端_為什么單線程Redis能那么快?

我們通常說&#xff0c;Redis 是單線程&#xff0c;主要是指 Redis 的網絡 IO 和鍵值對讀寫是由一個線程來完成的&#xff0c;這也是 Redis 對外提供鍵值存儲服務的主要流程。但 Redis 的其他功能&#xff0c;比如持久化、異步刪除、集群數據同步等&#xff0c;其實是由額外的線…

servlet中文亂碼處理

servlet中文亂碼處理 如果是post設置req.setCharacterEncoding("utf-8");如果是get&#xff0c;不去修改服務器配置的情況下new String(name.getBytes("iso-8859-1"),"utf-8")數據庫亂碼?useUnicodetrue&characterEncodingUTF-8轉載于:http…

C語言開發筆記(七)const和指針

const修飾變量是常用的&#xff0c;不容易犯錯&#xff0c;而const和指針一起使用時很容易混淆。 (一)const int *p #include <stdio.h>int main(void) {int a 10;int b 20;const int *p &a;*p b;return 0; } const在int *的左側&#xff0c;即指針指向內容為…

從JavaFX 1.3遷移到JavaFX 2.0

幾天前&#xff0c;我完成了將Modellus的源代碼從JavaFX 1.3腳本遷移到JavaFX 2.0 Java語言的過程。 因此&#xff0c;我認為寫關于我在此過程中學到的知識會很好。 我想指出&#xff0c;如果您想繼續在JavaFX 2.0中使用JavaFX腳本&#xff0c;則可以使用Visage&#xff1a; ht…

九度OJ 1034:尋找大富翁 (排序)

時間限制&#xff1a;1 秒 內存限制&#xff1a;32 兆 特殊判題&#xff1a;否 提交&#xff1a;5925 解決&#xff1a;2375 題目描述&#xff1a;浙江桐鄉烏鎮共有n個人,請找出該鎮上的前m個大富翁.輸入&#xff1a;輸入包含多組測試用例.每個用例首先包含2個整數n&#xff08…

ubuntu php 無法執行exec_利用webhook使php項目自動部署

php中文網最新課程每日17點準時技術干貨分享1.先來講一下自動部署的原理&#xff0c;一般在我們push代碼的時候&#xff0c;可以自動請求webhook中設置的url&#xff0c;完成一次請求與響應。那么只要我們設置的url地址請求的php文件內容是執行命令行git push命令&#xff0c;則…

android-verticalseekbar——Android可視化SeekBar類庫

android-verticalseekbar——Android可視化SeekBar類庫轉載于:https://www.cnblogs.com/zhujiabin/p/5706246.html

C語言開發筆記(八)static

在C語言中&#xff0c;static有3個作用&#xff1a; &#xff08;1&#xff09;在函數體&#xff0c;一個被聲明為靜態的變量在這一函數體內被調用的過程中維持其值不變。 #include <stdio.h>void test(void) {static int i 0;printf("%d\n", i); }int main…

ppt修復無法讀取_移動硬盤故障分析以及建議修復方法

移動硬盤中存儲了大量的重要數據&#xff0c;一旦出現什么問題&#xff0c;會讓人急得焦頭爛額。換個硬盤倒是件小事&#xff0c;但其中資料、數據的丟失更令人懊惱。而在硬盤使用的過程中&#xff0c;由于使用者一時的不注意&#xff0c;往往就很容易造成意外的問題。接下來&a…

(原創)c#學習筆記04--流程控制01--布爾邏輯03--運算符優先級

轉載于:https://www.cnblogs.com/wodehao0808/p/4896018.html

一些定義–測試技術9

我認為我即將結束有關測試技術的博客系列&#xff0c;感覺好像已經過去了。 對我來說更清楚的一件事是&#xff0c;測試方法仍處于起步階段&#xff0c;因此是開發人員之間爭執或討論的明確來源&#xff0c;這是一件好事。 我懷疑我們正處于職業發展史上的某個時刻&#xff0c;…

百度谷歌面試題目

全新整理&#xff1a;微軟、谷歌、百度等公司經典面試100題[第101-160題] 整理:July、二零一一年三月九日。應網友承諾與要求&#xff0c;全新整理。轉載&#xff0c;請注明出處。博主說明&#xff1a;此100題V0.2版&#xff0c;本人不再保證&#xff0c;還會提供答案。-------…