2012-01-12 42 views
4

在家長方面,我具有的屬性聲明如下:春季:在孩子方面替代屬性在運行時

<bean id="my.properties" 
     class="com.rcslabs.webcall.server.property.PropertyPaceholderConfigurer"> 
     <property name="locations" value="classpath:/my.properties"/> 
</bean> 

後,在運行時,我需要創建一個子上下文,並覆蓋與運行時數據的那些屬性。什麼是最好的方式來做到這一點?

此外:

更確切地說,我手工創建一個子上下文中運行時是這樣的:

ClassPathXmlApplicationContext childAppContext = new ClassPathXmlApplicationContext(parentApplicationContext); 

所以,我可以宣佈在childAppContext一個bean,像它通常使用BeanDefinitionRegistry完成?

回答

1

看起來你有一個PropertyPlaceholderConfigurer的子類,爲什麼不重寫resolveProperty,並檢查運行時值,然後再回到默認值?您可能必須爲子上下文創建專用子類,並在其中注入運行時值源。

您還可以做的是將您的運行時值設置爲系統屬性,並使用覆蓋模式systemPropertiesMode。這是一個簡單但不是很乾淨的解決方案,我的第一種方法的一些變化會更好。如果您創建多個客戶端上下文,只要您不會並行產生它們,就會工作。

更新:我喜歡的東西開始:

final Map<String,String> myRuntimeValues; 

ClassPathXmlApplicationContext childAppContext = new ClassPathXmlApplicationContext(parentApplicationContext) { 
    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { 
    super.prepareBeanFactory(); 
    beanFactory.registerSingleton("myRuntimeValues", myRuntimeValues); 
    } 
}; 

並注入「myRuntimeValues」到客戶端上下文文件中定義PropertyPlaceholderConfigurer豆。一些更多的挖掘可能會導致更好的解決方案,這不是一個典型的用例,我相信你會得到更遠的。

+0

是的,我實際上使用了一個默認PropertyPlaceholderConfigurer的子類,但是我該如何將**運行時值傳遞給那裏呢?另外,知道如何將某些東西注入到子環境中(並在之後使用它)會很有趣。 系統屬性不起作用,因爲實際上我會有N個子上下文。 – weekens 2012-01-12 12:30:40

+0

@weekens更新了我的回答 – mrembisz 2012-01-12 13:04:02

+0

好吧,它看起來非常好!可能,childAppContext.getBeanFactory()。registerSingleton(...)也可以工作(找不到正確的方法)。非常感謝! – weekens 2012-01-12 13:13:37

0

詳細闡述mrembisz的答案,下面是完整的示例,動態注入屬性到spring上下文中,而不用硬編碼子xml中的任何bean,然後從父上下文中傳遞bean引用。以下解決方案不需要爲此目的定義父上下文。

public static void main(String args[]) { 
    AbstractApplicationContext appContext = new ClassPathXmlApplicationContext(new String[] { "classpath:spring-beans.xml" }) { 
     protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { 
      super.prepareBeanFactory(beanFactory); 
      ArrayList<Properties> prList = new ArrayList<Properties>(); 
      Properties pr = new Properties(); 
      pr.setProperty("name", "MyName"); 
      prList.add(pr); 
      Properties prArray[] = new Properties[prList.size()]; 
      PropertySourcesPlaceholderConfigurer pConfig = new PropertySourcesPlaceholderConfigurer(); 
      pConfig.setPropertiesArray(prList.toArray(prArray)); 
      beanFactory.registerSingleton("pConfig", pConfig); 
     } 
    }; 
    appContext.refresh(); 
    System.out.println(appContext.getBean("name")); 
}