Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to declare a parent application context

Tags:

spring

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 from 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>
like image 491
Samo Avatar asked Nov 30 '10 19:11

Samo


People also ask

How do you declare an application context?

ApplicationContext context = new ClassPathXmlApplicationContext("applicationcontext/student-bean-config. xml"); StudentService studentService = context. getBean("studentService", StudentService. class);

What is parent context?

“parent context” is the name we use to name the context that would be inherited by the child (where child adds it own job to).

Can we have 2 application context in spring?

We can have multiple application contexts that share a parent-child relationship. A context hierarchy allows multiple child contexts to share beans which reside in the parent context. Each child context can override configuration inherited from the parent context.

Can we have multiple application context?

You can have two contexts within an application. If you have two contexts each will have its own singleton.


1 Answers

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.

like image 63
skaffman Avatar answered Sep 22 '22 11:09

skaffman