Spring Boot With XML Based Configuration
Ever wondered if we can use traditional XML configurations in Spring Boot, I had a requirement where my project used Spring 2.5 and all our beans were defined in traditional xml based configuration approach. Now we wanted to tap the power of Spring Boot so we thought what should we do, should we go ahead and convert our xml configuration to java based configuration or was there a way to merge the two.
Developers of Spring Boot wanted to handle such requirements and thus they allowed developers to use traditional xml configurations too. This was done mainly for those projects that used traditional xml based configuration and had to migrate to Spring Boot.
Let’s see how we can accomplish this, We will see a simple scenario of Setter Dependency injection in Spring Boot via XML Configuration.
Setter Injection Via Xml Based Configuration
Project Structure
Beans Defined
Car.java
public interface Car { void drive(); }
Alto.java
public class Alto implements Car { @Override public void drive() { System.out.println("alto drive"); } }
Swift.java
public class Swift implements Car { @Override public void drive() { System.out.println("swift drive"); } }
Employee.java
public class Employee { private String name; private Car car; public String getName() { return name; } public void setName(String name) { this.name = name; } public void setCar(Car car) { this.car = car; } public Car getCar() { return car; } public void showDetails() { System.out.println("employee " + name + " drives"); car.drive(); } }
Some theory I would like to add for above code
Class Employee which has Dependency on Car, which will be passed via setter injection.
Setter injection: When we pass dependency of an object via setter method then it is called setter injection, in below code example Employee has a dependency on Car ie Employee has a car.
Here instead of creating a car object directly like below
Car car=new Alto(); { Tight Coupling }
We use association ie we don’t directly create a car object
Lets see how we can achieve lose coupling
Association: Car car;
Setter method.
public void setCar(Car car) { this.car = car; }
Now the question comes how we pass the data to a setter method.
This dependency is passed via a configuration file . In our case an xml file. The responsibility of passing dependency is of Spring Container ie application context.
Employee (POJO Class) <—- Spring Core Container <— XML File
Employee has a dependency on Car.
XML file defines all our object we will see in below code.
Spring Core container is responsible for handling the interaction between two, ie handling dependency injection, we will see it soon.
XML File ( applicationContext.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" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean name="alto" class="com.springboot.withxml.beans.Alto" /> <bean name="swift" class="com.springboot.withxml.beans.Swift" /> <bean name="employee1" class="com.springboot.withxml.beans.Employee"> <property name="name" value="Kunal"></property> <property name="car" ref="alto"></property> </bean> </beans>
Want to add some theory for it:
Read More: JPA CRUD Operation in Spring boot
Here first we have created two Car objects
Spring Core when sees this.
<bean name="alto" class="com.springboot.withxml.beans.Alto" />
Object created:
Car alto=new Alto()
Similarly, Other objects are created
<bean name="swift" class="com.springboot.withxml.beans.Swift" />
Car swift=new Swift();
<bean name="employee1" class="com.springboot.withxml.beans.Employee"> <property name="name" value="Kunal"></property> <property name="car" ref="alto"></property> </bean> <bean name="employee1" class="com.springboot.withxml.beans.Employee"> Employee employee=new Employee(); <property name="name" value="Kunal"></property>
Using property tag we accomplish setter injection
employee.setName("Kunal")
<property name="car" ref="alto"></property>
employee.setCar(alto);
Main Class
@SpringBootApplication @ImportResource({ "classpath*:applicationContext.xml" }) public class Application { public static void main(String[] args) { ConfigurableApplicationContext ctx =SpringApplication.run(Application.class, args); Employee emp1 = (Employee) ctx.getBean("employee1"); emp1.showDetails(); } }
Output
employee Kunal drives alto drive
Theory:
@SpringBootAppliction @ImportResource({ "classpath*:applicationContext.xml" })
This is the line that does all the magic, import resource annotation imports the XML file from the classpath which is src/main/resources folder.
@SpringBootApplication already contains @Configuration so automatically this XML file gets loaded as a configuration file.
Understand @SpringBootApplication Annotation
Now the questions are how do we use beans defined in XML file. this is accomplished via application context object which is returned
ConfigurableApplicationContext ctx = SpringApplication.run(Application.class, args);
Now we can use the getBean method to get the bean from an XML file.
Employee emp1 = (Employee) ctx.getBean("employee1");
Employee1 is the name of bean defined in XML file.
Once we got the object we can use the methods of Employee Class.
I hope to know it is clear to use Spring Boot with an XML based configuration file.
Please leave us a comment if you have any issue. Happy to help