Spring Hello World Example: IoC Container and ClassPathXmlApplicationContext
This is the simplest possible Spring example. It shows the difference between creating an object with new and letting the Spring IoC container create it for you. The code is small, but the concept is the foundation of everything Spring does. Every Spring Boot application, every dependency injection, every bean — it all starts here.
What you need before you start
- JDK 8 or later installed.
- An IDE (Eclipse, IntelliJ, or VS Code) or a plain text editor and terminal.
- Spring Framework JAR files on the classpath. If you use Maven, add the
spring-contextdependency. If you use plain Java, download the Spring distribution and add the JARs to your classpath. - Apache Commons Logging JAR, which Spring depends on.
For Maven users, this single dependency brings in everything you need:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.30</version>
</dependency>
Project structure
Here is the folder layout. The XML file goes in the classpath root so that ClassPathXmlApplicationContext can find it.
spring-hello-world/
│
├── src/
│ └── main/
│ ├── java/
│ │ └── com/deepsingh44/model/
│ │ ├── HelloWorld.java
│ │ └── Test.java
│ └── resources/
│ └── spring_config.xml
Step 1: Create the HelloWorld bean
This is a plain Java class with one method. There is nothing Spring-specific here. That is the point — Spring does not force you to extend a class or implement an interface.
HelloWorld.java
package com.deepsingh44.model;
public class HelloWorld {
public void helloMessage() {
System.out.println("Hello World");
}
}
Step 2: Create the Spring configuration file
This XML file tells the IoC container which beans to create. A bean is just an object that Spring manages. The id is the name you will use to look it up. The class is the fully qualified class name.
spring_config.xml
<?xml version="1.0" encoding="UTF-8"?>
<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
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="h" class="com.deepsingh44.model.HelloWorld"></bean>
</beans>
This file says: "Create an object of class com.deepsingh44.model.HelloWorld and register it under the id h." That is all. The container does the rest.
Step 3: Write the test class
This class does the same thing twice. First the plain Java way. Then the Spring way. Compare the two.
Test.java
package com.deepsingh44.model;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
// ---------- Without Spring ----------
// You create the object yourself with new.
HelloWorld h = new HelloWorld();
h.helloMessage();
// ---------- With Spring ----------
// You do not write new HelloWorld().
// The IoC container reads spring_config.xml,
// creates the bean, and manages its lifecycle.
// You just ask for it by id.
ApplicationContext ac =
new ClassPathXmlApplicationContext("spring_config.xml");
Object o = ac.getBean("h");
HelloWorld hh = (HelloWorld) o;
hh.helloMessage();
}
}
Step 4: Compile and run
If you are using Maven, run:
mvn compile exec:java -Dexec.mainClass="com.deepsingh44.model.Test"
If you are using plain Java with the Spring JARs on your classpath, compile and run like this (Linux or Mac):
javac -cp ".:spring-context.jar:spring-core.jar:spring-beans.jar:commons-logging.jar" \
com/deepsingh44/model/*.java
java -cp ".:spring-context.jar:spring-core.jar:spring-beans.jar:commons-logging.jar" \
com.deepsingh44.model.Test
On Windows, replace : with ; in the classpath.
Output
Hello World
Hello World
You see the same line twice. The first comes from new HelloWorld(). The second comes from the bean the container created.
What is happening here
- First call:
new HelloWorld()creates the object directly. Your code is in control. - Second call:
ClassPathXmlApplicationContextreadsspring_config.xml, sees the bean with idh, creates theHelloWorldobject, and stores it. You ask for it withac.getBean("h"). The container hands it to you. - The point: You never wrote
new HelloWorld()for the second call. The container did. That is Inversion of Control — the control of object creation moves from your code to the framework.
Why this matters
In this small example, the benefit is not obvious. You could just write new HelloWorld() and move on. But imagine a real application with hundreds of classes. Imagine each class needs a database connection, a logger, a config reader. If every class creates its own dependencies with new, you end up with a tangled web of hard-coded objects that are impossible to test and impossible to swap out.
Spring flips the control. Your class declares what it needs. The container creates the objects and injects them. You change behavior by changing the XML (or later, the annotations), not by changing code.
That is the entire idea behind the IoC container. This Hello World is the smallest possible demonstration of it.
Common errors and how to fix them
| Error | Cause | Fix |
|---|---|---|
NoSuchBeanDefinitionException |
The bean id in getBean() does not match any <bean> id in the XML. |
Check the id spelling. It is case-sensitive. |
BeanDefinitionStoreException: IOException parsing XML document |
spring_config.xml is not on the classpath. |
Move it to src/main/resources or the classpath root. |
NoClassDefFoundError: org/springframework/context/ApplicationContext |
Spring JARs are not on the classpath. | Add spring-context, spring-core, spring-beans, and commons-logging. |
ClassCastException on the cast to HelloWorld |
The bean id points to a different class than you expect. | Check the class attribute in the XML. |
Where to go next
You now know how to create a bean, configure it in XML, and retrieve it using ClassPathXmlApplicationContext. That is the core of Spring's IoC container.
If you remember one thing, remember this: Spring does not do anything magic. It reads a config file, creates objects, and hands them to you when you ask. The only difference is that you did not write new.
If you want to go deeper, try these next steps:
- Add a second bean to
spring_config.xmlwith a different id but the same class. Retrieve both. Confirm they are separate objects. - Change
HelloWorldto have a constructor that takes aStringmessage. Pass that message through the XML using<constructor-arg>. Call the method and confirm the new message prints. - Replace
ClassPathXmlApplicationContextwith annotations:@Configuration,@Bean, andAnnotationConfigApplicationContext. Same output, different style. - Move on to Spring Boot. It removes the XML entirely and auto-configures most of what you just did by hand. Once you see what Boot does for you, the XML version makes much more sense.
No comments:
Post a Comment