2010-11-30 10 views
8

Ich finde mich zwei identische Beans in meiner applicationContext.xml und meine applicationContext-test.xml. Ich möchte, dass mein Testkontext von meinem App-Kontext erben kann, damit ich mich nicht wiederhole.So deklarieren Sie einen übergeordneten Anwendungskontext

Ich habe viel Material gesehen, das anzeigt, dass Sie einen übergeordneten Anwendungskontext deklarieren und Beans aus diesem Kontext referenzieren können, aber ich kann kein brauchbares Beispiel finden. Kann jemand helfen?

Kontext in meinen Unit-Tests geladen wird
<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> 

Meine Testanwendung:

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

aktualisieren Da einige Hintergrundinformationen, ist mein normaler Anwendungskontext in web.xml geladen Nehmen wir an, ich habe eine Bean in meinem regulären Kontext:

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

Dann möchte ich in meinem Testanwendungskontext auf diese Bohne verweisen. Wie mache ich es?

aktualisieren

Per skaffman Vorschlag habe ich die Bohne in eine SharedBeans.xml Datei verschoben und importiert sie in meine applicationContext.xml. Dies verursacht jedoch eine SAXParser Ausnahme:

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) 

ich kann nicht sicher sein, was ich falsch mache. Die Bean funktionierte gut in meiner Kontextdatei, und alles, was ich tat, wurde ausgeschnitten und in die neue Datei eingefügt. Hier sind die Inhalte von SharedBeans.xml in seiner Gesamtheit:

<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

Es hängt davon ab, wie Sie die Dinge eingerichtet haben. Bitte geben Sie ein Beispiel für die Verwendung Ihrer Kontexte. – skaffman

+0

@skaffman: Frage aktualisiert. Beispiele geschätzt. – Samo

+2

Sie brauchen immer noch die '' Top-Level-Element .... – skaffman

Antwort

5

Dies mich nicht schlagen als besonders guten Anwendungsfall für einen übergeordneten Kontext, was nützlich ist hauptsächlich eine Hierarchie aufzubauen (zB einer Wurzel Webapp-Kontext, mehrere Child-Servlet-Kontexte).

Für Ihre Situation wird es einfacher und einfacher zu verstehen, wenn Sie nur die gemeinsamen Bean-Definitionen in eine separate Datei extrahieren, und dann <import> sie in jede Kontextdatei, die es benötigt. Sie könnte dies mit Eltern-Kind-Kontexten tun, aber es wird schwieriger sein, unnötig zu verstehen.

OK, so ein Beispiel, es ausdrückte Ihre freigegebene Bean Definition in eine Datei shared-beans.xml genannt, und setzt (vorerst) auf der obersten Ebene Ihrer Classpath, bestehend aus:

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

Dann innen applicationContext-test.xml und /WEB-INF/classes/applicationContext.xml, fügen Sie folgendes:

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

Alle der Bohne Definitionen in shared-beans.xml wird nun in jedem App Kontext importiert werden. Sie erhalten damit keinen dritten App-Kontext, Sie importieren einfach die Bean-Definitionen aus einer anderen Datei.

+1

Könnten Sie bitte klären? Wenn Sie "eine separate Datei" sagen, ist dies eine Bohnenfabrik? Wenn nicht, was ist es? Sie sagen, dass ich sie aus dieser Datei importieren kann, aber können Sie ein Beispiel dafür geben, wie das gemacht wird? – Samo

+0

Ich erhalte eine SAXParser-Ausnahme. Bitte sehen Sie sich die aktualisierte Frage an. Ich bin mir nicht sicher, was ich falsch machen könnte. – Samo

0

Sie können Ihre allgemeine Deklaration in die separate XML-Datei verschieben und in den Klassenpfad einfügen (für einen einfachen Zugriff vom Test).Dann können Sie Folgendes tun:

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

Sie können auch common-beans.xml aus beiden Kontexten mit <import>, wie skaffman vorgeschlagen.

Verwandte Themen