I have approached this a little differently.
When running our integration/system tests, there are just a few components that need to be replaced with simulators. These components are defined in the production appcontext, and "overridden" in an integration-test appcontext, eg:
Production
Code:
<bean id="com.its.marketdata.realtimeCurrentPriceService"
class="com.its.marketdata.service.currentprice.RealTimeCurrentPriceServiceFactoryBean" lazy-init="true">
</bean>
<bean id="com.its.marketdata.delayedCurrentPriceService"
class="com.its.marketdata.service.currentprice.DelayedCurrentPriceServiceFactoryBean" lazy-init="true">
</bean>
Integration Test
Code:
<bean id="com.its.marketdata.simulatedCurrentPriceService"
class="test.ftest.trading.SimulatedCurrentPriceServiceFactoryBean">
</bean>
<bean id="ftest.beanOverrides"
class="test.ftest.trading.OverrideForTestBeanFactoryPostProcessor">
<property name="overrides">
<map>
<entry key="com.its.marketdata.realtimeCurrentPriceService">
<value>com.its.marketdata.simulatedCurrentPriceService</value>
</entry>
<entry key="com.its.marketdata.delayedCurrentPriceService">
<value>com.its.marketdata.simulatedCurrentPriceService</value>
</entry>
</map>
</property>
</bean>
The class OverrideForTestBeanFactoryPostProcessor handles swapping out the production AbstractBeanDefinition for the test version:
Code:
public class OverrideForTestBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
private Map overrides = new HashMap();
public void setOverrides(Map overrides) {
this.overrides = overrides;
}
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
for (Iterator beanNameIterator = overrides.keySet().iterator(); beanNameIterator.hasNext();) {
String beanName = (String)beanNameIterator.next();
String overrideBeanName = (String)overrides.get(beanName);
AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition)beanFactory.getBeanDefinition(beanName);
AbstractBeanDefinition overrideBeanDefinition = (AbstractBeanDefinition)beanFactory.getBeanDefinition(overrideBeanName);
beanDefinition.overrideFrom(overrideBeanDefinition);
}
}
}