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>
ApplicationContext context = new ClassPathXmlApplicationContext("applicationcontext/student-bean-config. xml"); StudentService studentService = context. getBean("studentService", StudentService. class);
“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).
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.
You can have two contexts within an application. If you have two contexts each will have its own singleton.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With