如何声明父应用程序上下文

8

我发现在我的applicationContext.xml和applicationContext-test.xml中使用了两个相同的bean。我希望我的测试环境可以继承我的应用程序上下文,以避免重复代码。

我看到很多资料表明可以声明一个父应用程序上下文并引用该上下文中的bean,但我找不到有用的示例。有人可以帮忙吗?

更新 作为一些背景信息,我的正常应用程序上下文在web.xml中被加载:

<context-param>
    <description>Application Contexts for Spring</description>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/classes/applicationContext.xml</param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> 

在我的单元测试中加载了我的测试应用程序上下文:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "/applicationContext-test.xml")

假设我有一个在常规上下文中的bean:

<bean name="someBean" class="com.foo.MyClass" />

那么,在我的测试应用程序上下文中,我想引用这个bean。我该怎么做?

更新

根据skaffman的建议,我将bean移动到SharedBeans.xml文件中,并将其导入到我的applicationContext.xml中。然而,这会导致SAXParser异常:

org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Failed to import bean definitions from URL location [classpath:SharedBeans.xml]
Offending resource: ServletContext resource [/WEB-INF/classes/applicationContext.xml]; nested exception is org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 1 in XML document from class path resource [SharedBeans.xml] is invalid; nested exception is org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'bean'.
    at org.springframework.beans.factory.parsing.FailFastProblemReporter.error(FailFastProblemReporter.java:68)

我不确定我做错了什么。在我的上下文文件中,这个bean工作得很好,而我所做的一切就是将其剪切并粘贴到新文件中。以下是SharedBeans.xml的全部内容:

<bean name="properties" class="com.foo.Properties">
    <constructor-arg><value>${module.name}</value></constructor-arg>
    <constructor-arg><value>${businessUnit}</value></constructor-arg>
    <constructor-arg><value>${product}</value></constructor-arg>
    <constructor-arg><value>${env}</value></constructor-arg>
    <constructor-arg><value>${machineName}</value></constructor-arg>
    <constructor-arg><value>${collectionSet.company}</value></constructor-arg>
    <constructor-arg><value>${route.tag}</value></constructor-arg>
    <constructor-arg><value>${timeout}</value></constructor-arg>      
</bean>

1
这取决于你如何设置事物。请举一个例子来说明你如何使用上下文。 - skaffman
@skaffman:问题已更新。欢迎提供示例。 - Samo
2
你仍然需要<beans>顶级元素... - skaffman
2个回答

5
这似乎不是父上下文的一个特别好的用例,因为它主要用于设置层次结构(例如一个根Web应用程序上下文,多个子servlet上下文)。
对于您的情况,如果您只是将通用的bean定义提取到单独的文件中,然后将其<import>到每个需要它的上下文文件中,这将更简单易懂。您可以使用父子上下文来完成此操作,但这样做会使事情变得更加难以理解,而且没有必要。
好的,举个例子,将共享的bean定义放入名为shared-beans.xml的文件中,并将其(暂时)放置在类路径的顶层,包含以下内容:
<bean name="someBean" class="com.foo.MyClass" />

然后,在applicationContext-test.xml/WEB-INF/classes/applicationContext.xml文件中添加以下内容:

<import resource="classpath:/shared-beans.xml" />

现在,shared-beans.xml 中的所有 bean 定义将被导入到每个应用程序上下文中。这样做并不会创建第三个应用程序上下文,而只是从另一个文件中导入 bean 定义。


1
请问您能否澄清一下?当您说“单独的文件”时,是指Bean工厂吗?如果不是,那它是什么?您说我可以从这个文件中导入它们,但您能否提供一个示例来演示如何完成此操作? - Samo
我遇到了SAXParser异常。请查看更新的问题。不确定我可能做错了什么。 - Samo

0

你可以将常用的声明移动到单独的XML文件中,并将其放置在类路径中(以便从测试中轻松访问)。然后,你可以执行以下操作:

<context-param> 
    <description>Application Contexts for Spring</description> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>
        /WEB-INF/classes/applicationContext.xml
        classpath:/common-beans.xml
    </param-value> 
</context-param> 

.

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(
    locations = {"/applicationContext-test.xml", "common-beans.xml"}) 

您还可以使用<import>从两个上下文中包含common-beans.xml,正如skaffman所建议的那样。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接