Skip to main content

Command Palette

Search for a command to run...

Techniques Spring Uses to Create Beans from beans.xml — The Hidden XML Parsing Journey Revealed

In the modern Spring Boot world, where annotations like @Configuration and @ComponentScan dominate, it’s easy to forget that the roots of Spring lie in XML-based configuration. But here’s the thing — even when you use annotations, the core mechan...

Published
5 min read
Techniques Spring Uses to Create Beans from beans.xml — The Hidden XML Parsing Journey Revealed
T

I am Tuanh.net. As of 2024, I have accumulated 8 years of experience in backend programming. I am delighted to connect and share my knowledge with everyone.

1. Introduction: Why Understanding XML Bean Creation Still Matters

1.1 How XML Configuration Fits into the Spring IoC Container

When Spring starts, it needs to know what beans exist and how they depend on each other. The beans.xml file acts as a blueprint. Here’s a minimal example:

<!-- beans.xml -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="greetingService" class="com.example.GreetingService"/>
<bean id="userController" class="com.example.UserController">
<property name="greetingService" ref="greetingService"/>
</bean>
</beans>

And a small Java driver:

public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserController controller = context.getBean(UserController.class);
controller.greet();
}
}

This simple-looking code hides a complex internal flow — Spring parses XML, constructs BeanDefinition objects, registers them in a BeanFactory, and finally instantiates them lazily or eagerly.

1.2 Step-by-Step: How Spring Parses the XML

When you call:

new ClassPathXmlApplicationContext("beans.xml");

Spring executes the following sequence:

  • ClassPathXmlApplicationContext delegates to a DefaultListableBeanFactory.
  • XmlBeanDefinitionReader is created to handle the parsing.
  • XmlBeanDefinitionReader.loadBeanDefinitions() reads the XML resource.
  • BeanDefinitionDocumentReader and DefaultBeanDefinitionDocumentReader traverse the XML DOM structure.
  • For every element, a BeanDefinition object is built using a BeanDefinitionParserDelegate.
  • Finally, all BeanDefinitions are stored in the BeanFactory registry.

At this point, no bean instance is created yet — only metadata is registered. Actual instantiation happens later during context refresh or lazy loading.

1.3 The Core Classes Involved in XML Parsing

Spring follows a delegation design pattern to isolate responsibilities. Here’s how each component contributes:

  • XmlBeanDefinitionReader: Acts as the entry point, responsible for loading XML resources and triggering document parsing.
  • BeanDefinitionDocumentReader: Defines how the root element should be interpreted.
  • BeanDefinitionParserDelegate: The heavy lifter that parses attributes like id, class, scope, and nested elements like .
  • DefaultListableBeanFactory: The ultimate container that stores every parsed BeanDefinition.

1.4 Code Example: Custom Logging of XML Parsing

Let’s make it real with a minimal demonstration that extends the parsing process.

public class CustomXmlReader extends XmlBeanDefinitionReader {

public CustomXmlReader(BeanDefinitionRegistry registry) {
super(registry);
}

@Override
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {
System.out.println(">>> Parsing XML: " + resource.getFilename());
return super.doLoadBeanDefinitions(inputSource, resource);
}
}

public class CustomContext extends ClassPathXmlApplicationContext {
@Override
protected void initBeanDefinitionReader(XmlBeanDefinitionReader reader) {
super.initBeanDefinitionReader(new CustomXmlReader(getBeanFactory()));
}
}

When you run it, you’ll see:

>>> Parsing XML: beans.xml

This confirms that XmlBeanDefinitionReader is the heart of the XML parsing process — and Spring allows you to hook into it for advanced introspection or bean preprocessing.

2. The Deeper Magic: From BeanDefinition to Bean Instance

Once Spring has registered all bean definitions, it moves into instantiation and dependency resolution.

2.1 The Role of BeanFactory in Bean Instantiation

When context.getBean("userController") is called, the container:

  • Looks up the corresponding BeanDefinition by ID.
  • Checks its scope (singleton by default).
  • Instantiates the class using reflection.
  • Injects dependencies defined via or constructor arguments.
  • Applies any BeanPostProcessor (like @Autowired processing).

This stage transforms static metadata into live, connected objects ready to serve your application.

2.2 How XML Influenced Spring Boot’s Annotation Model

You might think XML is obsolete, but it actually shaped today’s annotation-based configuration:

  • <bean> → @Bean
  • <context:component-scan> → @ComponentScan
  • <property> → @Autowired or constructor injection

Internally, both annotation and XML configurations are merged into the same BeanDefinition model, proving that Spring maintains backward compatibility by design.

2.3 Why You Should Care as a Developer

Understanding the XML parsing mechanism helps you:

  • Debug BeanCreationException at a much deeper level.
  • Write custom bean factories or namespace handlers (e.g., ).
  • Appreciate how Spring Boot auto-configuration builds upon the same core IoC principles.

For example, Spring Security, Spring Batch, and Spring Integration all define custom XML namespaces built on this foundation. They don’t reinvent the wheel—they extend the same XML parser delegates.

2.4 Reflection: A Bridge Between XML and Runtime Behavior

When the bean class is instantiated, Spring uses reflection:

Class<?> clazz = Class.forName("com.example.GreetingService");
Object bean = clazz.getDeclaredConstructor().newInstance();

This dynamic nature is why Spring can wire objects without compile-time dependencies — a core principle that makes DI containers powerful and extensible.

3. Conclusion: XML is Dead? Not Quite.

XML-based configuration may seem old-school, but it’s the DNA of Spring’s bean factory model. Every annotation-based configuration you write today still passes through the same underlying machinery.

Understanding how Spring parses beans.xml reveals the elegance of its design: modular, extensible, and backward-compatible. The next time you see a BeanDefinition, you’ll know that behind it lies a finely tuned orchestra of readers, delegates, and factories — all playing in perfect harmony.

Have a question or want me to dive deeper into custom XML namespace parsing? Drop a comment below and let’s discuss how to extend Spring’s bean definition mechanism for your own projects.

Read more at : Techniques Spring Uses to Create Beans from beans.xml — The Hidden XML Parsing Journey Revealed

More from this blog

T

tuanh.net

540 posts

Are you ready to elevate your Java, OOP, Spring, and DevOps skills? Look no further!

Techniques Spring Uses to Create Beans from beans.xml — The Hidden XML Parsing Journey Revealed