javascript
spring bean配置_在运行时交换出Spring Bean配置
spring bean配置
如今,大多數(shù)Java開發(fā)人員都定期與Spring打交道,而我們當中的許多人都已經(jīng)熟悉了它的功能和局限性。最近,我遇到了一個我從未遇到過的問題:引入了基于運行時引入的配置來重新連接Bean內(nèi)部的功能。 這對于簡單的配置更改或交換掉諸如Strategy或Factory類之類的東西很有用,而不是重建應用程序上下文的復雜部分。
我能夠找到一些有關如何執(zhí)行此操作的注釋,但我認為有些人可能會發(fā)現(xiàn)我的注釋和代碼示例很有用,特別是因為我可以確認該技術在Spring 1.2.6之前的版本中有效。 不幸的是,并不是我們所有人都有幸成為每個圖書館中最新最好的圖書館。
問題范圍
我將概述的方法主要是針對單個bean的更改,盡管可以輕松擴展此代碼以更改多個bean。 可以通過JMX或向管理員公開的其他UI調(diào)用它。
它沒有涵蓋的一件事是在整個應用程序中重新布線單例–可以想象,這可以通過對當前應用程序上下文的某種反思和檢查來完成,但是在大多數(shù)應用程序中,除非它們具有某種臨時關閉或關閉的方式,否則可能不安全。在整個應用程序中進行更改的同時,將所有處理阻塞一段時間。
代碼
這是示例代碼。 它將獲取一個包含bean定義的字符串列表,并將它們連接到新的臨時Spring上下文中。 您將看到可以提供父上下文,這在您的新bean定義需要引用應用程序中已經(jīng)配置的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沒有生命周期方法,該方法會導致它們在停止或破壞時處于無效狀態(tài)。
這是一個Spring上下文的示例,可用于重新連接組件。 想象一下,我們有一個電子商務系統(tǒng),可以進行欺詐檢查,但是可以使用多種策略來檢查欺詐。 我們可能希望從我們的服務類中交換這些內(nèi)??容,而不必停止并重新配置應用程序,因為這樣做會造成業(yè)務損失。 也許我們正在發(fā)現(xiàn)對該系統(tǒng)的特定濫用,可以通過更改用于定位欺詐性訂單的策略來更好地解決。
這是一個示例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();}}在那里,您擁有了! 可以適當?shù)財U展此示例以滿足您的需求,但是我認為它展示了如何動態(tài)創(chuàng)建Spring上下文并使用其bean重新配置應用程序而無需停機的基礎知識。
參考: 在運行時從我們的JCG合作伙伴的Carfey Software博客上 交換Spring Bean配置 。
相關文章 :- 零XML的Spring配置
- Spring依賴注入技術的發(fā)展
- Spring MVC3 Hibernate CRUD示例應用程序
- 使用Spring AOP進行面向方面的編程
- Spring MVC開發(fā)–快速教程
翻譯自: https://www.javacodegeeks.com/2011/09/swapping-out-spring-bean-configuration.html
spring bean配置
總結
以上是生活随笔為你收集整理的spring bean配置_在运行时交换出Spring Bean配置的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Netflix Archaius用于物业
- 下一篇: 微众银行每月有扣费吗?