[英]Create ApplicationContext as Spring bean (by other application context)
我如何在其他應用程序上下文中將一個ApplicationContext定義為原型spring bean。 此外,我需要將當前上下文作為父應用程序上下文傳遞。
細節:
我有Bean,代表富客戶端應用程序中的一個用戶會話。 此類管理應用程序上下文的生命周期,以及其他一些對象(如數據庫連接)。 此會話bean本身由特殊的“啟動應用程序上下文”配置。
現在我想要對這個會話bean進行單元測試,但由於在會話bean中創建了會話特定的應用程序上下文,並且有許多依賴於“啟動上下文”,所以有麻煩;
示例代碼:
public class UserDBAminSession implements ApplicationContextAware, UserSession {
ApplicationContext startupContext;
ApplicationContext sessionContext;
public void setApplicationContext(ApplicationContext startupContext) {...}
public void start() {
createSessionContext() ;
}
private void createSessionContext() {
sessionContext = new ClassPathXmlApplicationContext("admin-session.xml", startupContext);
}
}
出於測試目的,我想復制createSessionContext函數代碼,如下所示:
sessionContext = startupContext.getBean("adminContext", ApplicationContext.class);
然后我可以創建startupContext的模擬,返回一些存根。 或者甚至DI“會話上下文”到春天的bean,在某個未來。 但是,我不知道如何將父上下文參數傳遞給ClassPathXmlApplicationContext構造函數。 我嘗試這樣的東西,但似乎不起作用:
<bean id="adminContext" class="org.springframework.context.support.ClassPathXmlApplicationContext"
scope="prototype" autowire="constructor">
<constructor-arg type="java.lang.String">
<value>admin-session.xml</value>
</constructor-arg>
</bean>
此外,我考慮在頂層創建應用程序上下文並通過setter傳遞它,但是:
或者制作特殊的“上下文工廠”對象,但它已經不是最好的代碼了。
什么看起來很愚蠢,我不能從IoC框架本身的IoC對象。 可能是我誤讀了一些彈簧文檔?
還有其他想法,如何對這個類進行單元測試?
使用FactoryBean
和ApplicationContextAware
接口。
public class ChildApplicationContextFactoryBean implements FactoryBean, ApplicationContextAware {
protected String[] configLocations;
protected ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override
public Object getObject() throws Exception {
return new ClassPathXmlApplicationContext(configLocations, applicationContext);
}
@Override
public Class getObjectType() {
return ClassPathXmlApplicationContext.class;
}
@Override
public boolean isSingleton() {
return true;
}
public void setConfigLocations(String[] configLocations) {
this.configLocations = configLocations;
}
}
用法:
<bean class="com.skg.ecg.portal.operation.transit.ChildApplicationContextFactoryBean">
<property name="configLocations">
<list>
<value>applicationContext.xml</value>
</list>
</property>
</bean>
如果我理解正確,您的要求是在手動控制的范圍內管理一組bean(在本例中為RIA會話)。
Spring支持scoped bean 。 您擁有基本的singleton
和prototype
范圍,而webapps也可以獲取request
和session
范圍。 如果您的RIA會話實際上是一個HTTP會話,那么我建議您使用session
-scoped bean而不是手動嵌套的應用程序上下文設計。
如果您的會話與網絡無關,那么您仍然可以選擇自定義自定義范圍 。 在這方面還有更多工作,但它是容器中定義的擴展點,因此您處於安全的地方。
你最初認為應用程序上下文本身就是父上下文中的bean會起作用,是的,但在這種情況下它可能是不必要的,只會增加復雜性。 但是,如果要進一步研究它,請查看SingletonBeanFactoryLocator
,它是一個用於管理應用程序上下文層次結構的Spring基礎結構類。 它不會做你想要的具體工作,但它可能會給你一些想法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.