开发者

How to declare a parent application context

I find myself using two identical beans in my applicationContext.xml and my applicationContext-test.xml. I'd like my test context to be able to inherit from my app context, to avoid repeating myself.

I've seen plenty of material indicating that you can declare a parent application context and reference beans fro开发者_如何学JAVAm that context, but I can't find a useful example. Can anyone help?

Update As some background info, my normal application context is being loaded in 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> 

My test application context is loaded in my unit tests:

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

So let's say I have a bean in my regular context:

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

Then, in my test application context, I'd like to refer to this bean. How do I do it?

Update

Per skaffman's suggestion, I've moved the bean into a SharedBeans.xml file and imported it into my applicationContext.xml. However, this causes a SAXParser exception:

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)

I can't be sure what I'm doing wrong. The bean was working fine in my context file, and all I did was cut and paste into the new file. Here are the contents of SharedBeans.xml in its entirety:

<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>


This doesn't strike me as a particularly good use-case for a parent context, which is useful mainly to set up a hierarchy (e.g. one root webapp context, multiple child servlet contexts).

For your situation, it's going to be simpler and easier to understand if you just extract the common bean definitions into a separate file, and then <import> them into each context file that needs it. You could do this with parent-child contexts, but it's going to be harder to understand, unnecessarily so.

OK, so an example, put your shared bean definition into a file called shared-beans.xml, and put it (for now) at the top-level of your classpath, containing:

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

Then, inside applicationContext-test.xml and /WEB-INF/classes/applicationContext.xml, add the following:

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

All of the bean definitions in shared-beans.xml will now be imported into each app context. You don't get a third app-context by doing this, you just import the bean definitions from another file.


You can move your common declaration to the separate XML file and place it in classpath (for easy access from test). Then you can do the following:

<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"}) 

You can also include common-beans.xml from both contexts using <import>, as suggested by skaffman.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜