Spring Framework bean definition XML: custom tag

At first

In document of Spring Framework, there is an example of define bean by using XML element "<util:list>". https://docs.spring.io/spring/docs/5.0.x/spring-framework-reference/core.html#xsd-schemas-util-list

<!-- creates a java.util.List instance with the supplied values -->
<util:list id="emails">
    <value>[email protected]</value>
    <value>[email protected]</value>
    <value>[email protected]</value>
    <value>[email protected]</value>
</util:list>

The code above has same function of below code.

<!-- creates a java.util.List instance with values loaded from the supplied 'sourceList' -->
<bean id="emails" class="org.springframework.beans.factory.config.ListFactoryBean">
    <property name="sourceList">
        <list>
            <value>[email protected]</value>
            <value>[email protected]</value>
            <value>[email protected]</value>
            <value>[email protected]</value>
        </list>
    </property>
</bean>

I am interest in this magic, so I start to look into source code.

The turth of magic

First, I tried to find out classes which implement interface org.springframework.beans.factory.xmlBean.DefinitionParser in Eclipse. A lot of classes came out. And one of class org.springframework.beans.factory.xml.UtilNamespaceHandler (In Java archive spring-beans-3.2.3.RELEASE.jar) I felt suspect. So I read the code of this

java:org.springframework.beans.factory.xml.UtilNamespaceHandler


...
	public void init() {
		registerBeanDefinitionParser("constant", new ConstantBeanDefinitionParser());
		registerBeanDefinitionParser("property-path", new PropertyPathBeanDefinitionParser());
		registerBeanDefinitionParser("list", new ListBeanDefinitionParser());
		registerBeanDefinitionParser("set", new SetBeanDefinitionParser());
		registerBeanDefinitionParser("map", new MapBeanDefinitionParser());
		registerBeanDefinitionParser("properties", new PropertiesBeanDefinitionParser());
	}
...

May be I found out the class which handle XML element "list". In the same Java archive, I tried to look into "/META-INF/spring.handlers"

http\://www.springframework.org/schema/c=org.springframework.beans.factory.xml.SimpleConstructorNamespaceHandler
http\://www.springframework.org/schema/p=org.springframework.beans.factory.xml.SimplePropertyNamespaceHandler
http\://www.springframework.org/schema/util=org.springframework.beans.factory.xml.UtilNamespaceHandler

Bingo! Elements in "util" namespace is really handle by class org.springframework.beans.factory.xml.UtilNamespaceHandler. Return to method init(). XML element "list" is handle by class ListBeanDefinitionParser(inner class of org.springframework.beans.factory.xml.UtilNamespaceHandler).

java:org.springframework.beans.factory.xml.UtilNamespaceHandler


...
	private static class ListBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {

		@Override
		protected Class getBeanClass(Element element) {
			return ListFactoryBean.class;
		}

		@Override
		protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
			String listClass = element.getAttribute("list-class");
			List parsedList = parserContext.getDelegate().parseListElement(element, builder.getRawBeanDefinition());
			builder.addPropertyValue("sourceList", parsedList);
			if (StringUtils.hasText(listClass)) {
				builder.addPropertyValue("targetListClass", listClass);
			}
			String scope = element.getAttribute(SCOPE_ATTRIBUTE);
			if (StringUtils.hasLength(scope)) {
				builder.setScope(scope);
			}
		}
	}
...

Method getBeanClass() is for getting List bean factory class org.springframework.beans.factory.config.ListFactoryBean. And method doParse() is for reading XML element properties and child element.

Reference https://docs.spring.io/spring/docs/5.0.x/spring-framework-reference/core.html#xml-custom

Recommended Posts

Spring Framework bean definition XML: custom tag
Overwrite bean definition in spring xml configuration file with another xml
spring framework Simple study memo (1): ApplicationContext, Bean, Autowired
[Spring Framework] Configuration split
Spring Framework multilingual support
Spring bean life cycle
1. Start Spring framework from 1
Spring Framework Summary-About DI