![](/img/trans.png)
[英]How to re-created a Singleton bean on Spring if the Singleton crashes?
[英]Re-registering singleton bean on Spring
我有一個多模塊項目,每個模塊都有自己的單元測試,並為該模塊的類提供模擬。
我正在嘗試構建一個應用程序上下文,其中每個模塊都可以定義自己的模擬,但后來的單元測試將能夠覆蓋這些模擬,例如:
public class Test {
private static final class StupidMock {
}
@org.junit.Test
public void test() {
StaticApplicationContext applicationContext = new StaticApplicationContext();
final ConfigurableListableBeanFactory beanFactory = applicationContext.getBeanFactory();
StupidMock stupidMock = new StupidMock(); // original mock
beanFactory.registerSingleton(StupidMock.class.getName(), stupidMock);
StupidMock f1 = applicationContext.getBean(StupidMock.class);
if (f1 == null || f1 != stupidMock) { // ensuring mock is retrievable
fail("Could not get bean");
}
for (String names2Remove : beanFactory.getBeanNamesForType(StupidMock.class)) {
applicationContext.removeBeanDefinition(names2Remove); // <-- fails here
}
StupidMock stupidMock2 = new StupidMock(); // replacement mock
beanFactory.registerSingleton(StupidMock.class.getName(), stupidMock2);
}
}
問題是這個簡單的片段在嘗試刪除第一個模擬時失敗,聲稱沒有這樣的bean(盡管Spring剛剛成功地為我提供了一個名字)。
如果我只是嘗試在第一個上面注冊另一個模擬,Spring抱怨說已經存在對象限制。
DefaultSingletonBeanRegistry
有一個受保護的removeSingleton
方法,但是我無法控制StaticApplicationContext
擁有的bean工廠。 我可以使用反射並且無論如何都要調用這個受保護的方法,但是對於這樣一個簡單的任務來說這樣做是錯誤的。
我究竟做錯了什么? 如何在StaticApplicationContext
上實現單例替換?
這里的問題是registerSingleton方法實際上沒有創建相應的BeanDefinition ,它只是注冊實例化的單例,將它與你提供的名稱相關聯,然后通過應用程序上下文檢索它 - 盡管它沒有底層的BeanDefinition。
所以當你調用applicationContext.removeBeanDefinition(names2Remove);
它失敗,因為沒有bean定義 ,只有已注冊的完全實例化的bean。
修復是不使用registerSingleton,而是使用一個使用BeanDefinition的registerSingleton形式:
Map<String, String> map = new HashMap<String, String>();
map.put("i", "10"); // set all the properties for the mock..
MutablePropertyValues propertyValues = new MutablePropertyValues(map);
beanFactory.registerSingleton(StupidMock.class.getName(), StupidMock.class, propertyValues);
您可以使用spring-reinject重新定義bean。
如果您使用的是spring框架,為什么不使用Spring測試框架
您可以使用以下注釋在每個單元測試的基礎上進行特定的模擬
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.