Issue
I have a Java application that parses an xml file of the following format.
<x:foo xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:x="http://www.hello.org/x/foo"
xsi:schemaLocation="http://www.hello.org/x/foo http://schemas.hello.org/x/foo-1.0.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd">
<x:myBeans>
<bean id="my-bean-1" class="org.hello.sample.SampleClass1">
<!-- some properties goes here -->
</bean>
<bean id="my-bean-2" class="org.hello.sample.SampleClass2">
<!-- some properties goes here -->
</bean>
<import resource="sub-file.xml"/>
</x:myBeans>
<x:otherElements>
<!-- Some non-spring xml elements (which are not used by application logic) goes here -->
</x:otherElements>
</x:flow>
The myBeans tag contains a set of native spring beans and import statements. The otherElements tag contains a set of elements that are only used by a separate application which generates this file. My application is only interested in those spring beans and imports.
So I'm using the following custom bean parser to parse this file and add the spring bean definitions to the spring context.
public class MyBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
Element myBeansElement = DomUtils.getChildElementByTagName(element, "myBeans");
if (myBeansElement != null) {
// Parsing 'bean' elements
List<Element> beanElements = DomUtils.getChildElementsByTagName(myBeansElement, "bean");
for (Element beanElement : beanElements) {
BeanDefinitionHolder bdh = parserContext.getDelegate().parseBeanDefinitionElement(beanElement);
parserContext.getRegistry().registerBeanDefinition(bdh.getBeanName(), bdh.getBeanDefinition());
}
// Parsing 'import' statements
List<Element> importElements = DomUtils.getChildElementsByTagName(myBeansElement, "import");
for (Element importElement : importElements) {
// TODO
}
}
}
}
The parsing and adding spring beans (my-bean-1, my-bean-2) to the context works fine. But how can I parse and add the beans defined in the file sub-file.xml (which has the same structure) to the spring context?
Solution
I was able to get the above working as follows.
// Parsing 'import' statements
List<Element> importElements = DomUtils.getChildElementsByTagName(myBeansElement, "import");
Resource currentResource = parserContext.getReaderContext().getResource();
for (Element importElement : importElements) {
String importPath = importElement.getAttribute("resource");
try {
Resource importResource = currentResource.createRelative(importPath);
parserContext.getReaderContext().getReader().loadBeanDefinitions(importResource);
} catch (IOException | BeanDefinitionStoreException e) {
e.printStackTrace();
}
}
Also I had to parse the import statements before the bean elements, so that the bean refs are not broken.
Answered By - Udith Gunaratna