如何覆盖在应用程序上下文中定义的单个bean

tin*_*tin 6 spring spring-mvc spring-3

我有一个访问外部Web服务的Web应用程序.我正在为Web应用程序编写自动验收测试套件.我不想调用外部Web服务,因为它有严重的开销,我想模拟这个Web服务.如何在不改变Web应用程序的应用程序上下文的情况下实现这一目标?我们最近迁移到Spring 3.1,所以我很想使用新的环境功能.这些新功能是否可以帮助我覆盖这个单一的Web服务并保留应用程序上下文的原样?

sea*_*ges 9

我会使用Spring @Profile功能,我假设它是你所指的"环境功能".

例如:

@Service @Profile("dev")
public class FakeWebService implements WebService {
}

@Service @Profile("production")
public class ExternalWebService implements WebService {
}
Run Code Online (Sandbox Code Playgroud)

编辑

并指定在测试中使用的配置文件:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/app-config.xml")
@ActiveProfiles("dev")
public class MyAcceptanceTest {
}
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,请参阅Spring文档的此部分.

有几种方法可以在生产中设置活动配置文件,但我之前使用的方法是在web.xml中:

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>spring.profiles.active</param-name>
        <param-value>production</param-value>
    </init-param>
</servlet>
Run Code Online (Sandbox Code Playgroud)


nic*_*ild 4

我将使用 aBeanFactoryPostProcessor来执行此操作,它仅在您希望模拟的测试场景中注册。

允许BeanFactoryPostProcessor您在创建和填充应用程序上下文后立即对其进行修改。您可以查找特定 bean 的名称,并为其注册一个不同的 bean。

public class SystemTestBeanFactoryPostProcessor implements BeanFactoryPostProcessor
{
    @Override
    public void postProcessBeanFactory(final ConfigurableListableBeanFactory factory) throws BeansException
    {
        final MyInterface myInterface = new MyInterfaceStub();
        factory.registerSingleton("myInterfaceBeanName", myInterface);
    }
}
Run Code Online (Sandbox Code Playgroud)

这将允许您仅覆盖您想要存根/模拟的 bean。

我不确定这是做此类事情的“最新 3.x”方式。但它非常简单且易于实施。