<p dir="auto"><strong><a href="https://jira.spring.io/secure/ViewProfile.jspa?name=sterenb2" rel="nofollow">Geert Jan Sterenborg</a></strong> opened <strong><a href="https://jira.spring.io/browse/SPR-3184?redirect=false" rel="nofollow">SPR-3184</a></strong> and commented</p>
<p dir="auto">Hi,</p>
<p dir="auto">Currently we have a config-module for every specific implementation of our product. These config-modules contain our Spring configuration-files.<br>
So we have a lot of duplicate bean-configs.</p>
<p dir="auto">We initialize the configuration files like so:</p>
<p dir="auto">---start of boot-strap.xml<br>
[CODE]&lt;bean id="core-services" class="....ServiceManager"&gt;<br>
&lt;constructor-arg&gt;<br>
&lt;list&gt;<br>
&lt;value&gt;services/config-file.xml&lt;/value&gt;<br>
&lt;/list&gt;<br>
&lt;/constructor-arg&gt;<br>
&lt;/bean&gt;[/CODE]<br>
---end of boot-strap.xml</p>
<p dir="auto">I'm trying to split these modules into a kernel-config-module (i.e. generic-config-modules) and several specific-config modules making use of the parent-child relationship.</p>
<p dir="auto">The problem I'm running into is the following:</p>
<p dir="auto">Generic config-file:<br>
[CODE]<br>
&lt;bean id="a" class="...A"&gt;<br>
&lt;constructor-arg ref="c"&gt;<br>
&lt;/bean&gt;</p>
<p dir="auto">&lt;bean id="b" class="...B"&gt;<br>
&lt;constructor-arg ref="a"&gt;<br>
&lt;/bean&gt;</p>
<p dir="auto">&lt;bean id="c" class="...C"/&gt;[/CODE]</p>
<p dir="auto">Bean A - uses bean C in generic config-file<br>
Bean B - uses bean A in generic config-file</p>
<p dir="auto">Specific config-file:</p>
<p dir="auto">[CODE]&lt;bean id="a" parent="a"&gt;<br>
&lt;constructor-arg ref="d"&gt;<br>
&lt;/bean&gt;[/CODE]</p>
<p dir="auto">&lt;bean id="d" class="...D"/&gt;</p>
<p dir="auto">Bean A - overrides bean A in generic config-file so that it uses bean D (config: &lt;bean id="a" parent="a"&gt;....)<br>
Bean D - Some bean</p>
<p dir="auto">And the boot-strap-files:</p>
<p dir="auto">---start of boot-strap-kernel.xml<br>
[CODE] &lt;bean id="core-services-kernel" class="....ServiceManager"&gt;<br>
&lt;constructor-arg&gt;<br>
&lt;list&gt;<br>
&lt;value&gt;services/config-file-kernel.xml&lt;/value&gt;<br>
&lt;/list&gt;<br>
&lt;/constructor-arg&gt;<br>
&lt;/bean&gt;[/CODE]<br>
---end of boot-strap-kernel.xml</p>
<p dir="auto">---start of boot-strap-specific.xml<br>
[CODE]   &lt;bean id="core-services" class="....ServiceManager"&gt;<br>
&lt;constructor-arg&gt;<br>
&lt;list&gt;<br>
&lt;value&gt;services/config-file.xml&lt;/value&gt;<br>
&lt;/list&gt;<br>
&lt;/constructor-arg&gt;<br>
&lt;constructor-arg ref="core-services-kernel"/&gt;&lt;!--Generic is core-services' parent --&gt;<br>
&lt;/bean&gt;[/CODE]<br>
---end of boot-strap-kernel.xml</p>
<p dir="auto">The problem is that generic-bean B still uses the generic-bean A.</p>
<p dir="auto">In order to use generic-bean B without having to include it in all specific-config-modules I could add a generic-config-file,<br>
include it in core-services and move bean B to this file:</p>
<p dir="auto">---start of boot-strap-specific.xml<br>
[CODE]   &lt;bean id="core-services" class="....ServiceManager"&gt;<br>
&lt;constructor-arg&gt;<br>
&lt;list&gt;<br>
&lt;value&gt;services/config-file-kernel-shared.xml&lt;/value&gt;<br>
&lt;value&gt;services/config-file.xml&lt;/value&gt;<br>
&lt;/list&gt;<br>
&lt;/constructor-arg&gt;<br>
&lt;constructor-arg ref="core-services-kernel"/&gt;&lt;!--Generic is core-services' parent --&gt;<br>
&lt;/bean&gt;[/CODE]<br>
---end of boot-strap-kernel.xml</p>
<p dir="auto">But what if I want to override bean B?</p>
<p dir="auto">The alternative is to move bean B to the specific config-file. If there were other beans depending on B they would have to be moved (in this case duplicated) too.</p>
<p dir="auto">Some forum-questions and issues regarding this matter all boil down to the fact that parent-contexts know nothing of their children.</p>
<p dir="auto">I'm not entirely sure but I guess the goal is that bean-extension should compare to java class-extension.<br>
However since I'm going through the child-context to access bean B that is configured in the parent-context it wouldn't be completely illogic to be able to override the parent-definition.</p>
<p dir="auto">It would be nice to have an extension that would allow to do something like this:</p>
<p dir="auto">[CODE]&lt;bean id="a" .... parent="a"&gt;<br>
&lt;override/&gt; &lt;!--- override switch --&gt;<br>
&lt;constructor-arg ref="d"&gt;<br>
&lt;/bean&gt;[/CODE]</p>
<p dir="auto">The override tag should completely override bean A (in child-context as well as parent-context.)</p>
<p dir="auto">I've posted this as a question on the forum (<a href="http://forum.springframework.org/showthread.php?t=34950" rel="nofollow">http://forum.springframework.org/showthread.php?t=34950</a>), but perhaps it could be useful to others if it were included in the core.</p>
<hr>
<p dir="auto">No further details from <a href="https://jira.spring.io/browse/SPR-3184?redirect=false" rel="nofollow">SPR-3184</a></p>
<p dir="auto"><strong><a href="https://jira.spring.io/secure/ViewProfile.jspa?name=chess2001" rel="nofollow">Vladimiras Makarovas</a></strong> opened <strong><a href="https://jira.spring.io/browse/SPR-3316?redirect=false" rel="nofollow">SPR-3316</a></strong> and commented</p>
<p dir="auto">spring-framework-2.0.4-with-dependencies-20070327-26.zip</p>
<p dir="auto">trace:<br>
javax.security.auth.login.LoginException: org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from class path resource [conf/netsvep-aas-context.xml]; nested exception is java.lang.IllegalArgumentException: Class [org.springframework.beans.factory.xml.SimplePropertyNamespaceHandler] does not implement the NamespaceHandler interface<br>
Caused by: java.lang.IllegalArgumentException: Class [org.springframework.beans.factory.xml.SimplePropertyNamespaceHandler] does not implement the NamespaceHandler interface<br>
at org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver.initHandlerMappings(DefaultNamespaceHandlerResolver.java:119)<br>
at org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver.&lt;init&gt;(DefaultNamespaceHandlerResolver.java:96)<br>
at org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver.&lt;init&gt;(DefaultNamespaceHandlerResolver.java:82)<br>
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.createDefaultNamespaceHandlerResolver(XmlBeanDefinitionReader.java:489)<br>
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.createReaderContext(XmlBeanDefinitionReader.java:478)<br>
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:458)<br>
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:353)<br>
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:303)<br>
at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:280)<br>
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:131)<br>
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:147)<br>
at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:173)<br>
at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:112)<br>
at org.springframework.context.support.AbstractXmlApplicationContext.loadBeanDefinitions(AbstractXmlApplicationContext.java:79)<br>
at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:100)<br>
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:298)<br>
at org.springframework.context.support.ClassPathXmlApplicationContext.&lt;init&gt;(ClassPathXmlApplicationContext.java:91)<br>
at org.springframework.context.support.ClassPathXmlApplicationContext.&lt;init&gt;(ClassPathXmlApplicationContext.java:75)<br>
at org.springframework.context.support.ClassPathXmlApplicationContext.&lt;init&gt;(ClassPathXmlApplicationContext.java:65)<br>
at com.asw.netsvep.modules.aas.DatabaseServerLoginModuleRC.getAuthService(Unknown Source)</p>
<p dir="auto">code:<br>
protected DatabaseServerAuthService getAuthService() {<br>
String path = "classpath:conf/netsvep-aas-context.xml";<br>
ApplicationContext ctx = new ClassPathXmlApplicationContext(path);<br>
DatabaseServerAuthService auth = (DatabaseServerAuthService) ctx.getBean("authService");<br>
return auth;<br>
}</p>
<hr>
<p dir="auto"><strong>Affects:</strong> 2.0.4</p>