Spring Dependency Injection using Setter Injection and XML Configuration
I have used Spring way back in my career, but I have been lately using again at work. In this blog post, I am going to explain how to use dependency injection in spring using setter injection and XML configuration. This blog post assumes you already have Java and Maven installed.
Step 1: Create a Java Project using Maven
mvn archetype:generate \
-DgroupId=com.mycompany.productstore \
-DartifactId=product_store_xml_setter_injection \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DinteractiveMode=false
Step 2: Let’s create some placeholder folders
cd product_store_xml_setter_injection/src/main
mkdir resources
cd java/com/mycompany/productstore
mkdir model service repository
Step 3: Create the model class
src/main/java/com/mycompany/productstore/model/Product.java
package com.mycompany.productstore.model;
public class Product {
private String name;
private double price;
private int quantity;
public Product(String name, double price, int quantity) {
this.name = name;
this.price = price;
this.quantity = quantity;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
}
Step 4: Create a repository interface and its implementation class
src/main/java/com/mycompany/productstore/repository/ProductRepository.java
package com.mycompany.productstore.repository;
import com.mycompany.productstore.model.Product;
import java.util.List;
public interface ProductRepository {
List<Product> getAllProducts();
}
src/main/java/com/mycompany/productstore/repository/ProductRepositoryImpl.java
package com.mycompany.productstore.repository;
import com.mycompany.productstore.model.Product;
import java.util.ArrayList;
import java.util.List;
public class ProductRepositoryImpl implements ProductRepository {
public List<Product> getAllProducts() {
List<Product> productList = new ArrayList<Product>();
productList.add(new Product("Laptop", 100, 2));
productList.add(new Product("Phone", 250, 3));
productList.add(new Product("Keyboard", 50, 1));
return productList;
}
}
Generally, in the business applications, the repository implementation class connects to the database. But for the simplicity of this blog post, I am returning some hardcoded values.
Step 5: Create a service interface and its implementation class
src/main/java/com/mycompany/productstore/service/ProductService.java
package com.mycompany.productstore.service;
import com.mycompany.productstore.model.Product;
import java.util.List;
public interface ProductService {
List<Product> getAllProducts();
}
src/main/java/com/mycompany/productstore/service/ProductServiceImpl.java
package com.mycompany.productstore.service;
import com.mycompany.productstore.model.Product;
import com.mycompany.productstore.repository.ProductRepository;
import java.util.List;
public class ProductServiceImpl implements ProductService {
private ProductRepository productRepository;
public void setProductRepository(ProductRepository productRepository) {
this.productRepository = productRepository;
}
public List<Product> getAllProducts() {
return productRepository.getAllProducts();
}
}
The ProductServiceImpl class is dependent on ProductRepository object to get the products, instead of creating an object for its implementation class ProductRepositoryImpl we created a setter for ProductRepository interface. In the next steps, we use spring dependency injection to inject the object of ProductRepositoryImpl into ProductService class using setter method of ProductRepository interface at runtime.
Step 6: Add the spring (spring-context) to our project in the pom.xml file
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.productstore</groupId>
<artifactId>product_store_xml_setter_injection</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>product_store_xml_setter_injection</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
The spring-context jar is enough to use the dependency injection.
Step 7: Let’s create the beans configuration using XML in applicationContext.xml file
src/main/resources/applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean name="productRepositoryImpl"
class="com.mycompany.productstore.repository.ProductRepositoryImpl"/>
<bean name="productServiceImpl"
class="com.mycompany.productstore.service.ProductServiceImpl">
<property name="productRepository" ref="productRepositoryImpl"/>
</bean>
</beans>
In the above bean configuration first, we created ProductRepositoryImpl bean. Next, we created ProductServiceImpl bean. As ProductServiceImpl class dependent on ProductRepositoryImpl object, we passed it has dependency using property tag.
Step 8: Let’s the spring ApplicationContext to test whether we can get the beans dynamically and it whether the dependencies are injected or not.
src/main/java/com/mycompany/productstore/App.java
package com.mycompany.productstore;
import com.mycompany.productstore.model.Product;
import com.mycompany.productstore.service.ProductService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.List;
public class App {
public static void main(String[] args) {
ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext.xml");
ProductService productService = appContext.getBean(ProductService.class);
List<Product> productsList = productService.getAllProducts();
System.out.println("---- Products ----");
for (Product product : productsList) {
System.out.println(product.getName());
}
}
}
We created the spring application context using beans configuration created in applicationContext.xml, and then we are using getBean() method to get the ProductService object. At this stage spring already created the ProductRepositoryImpl object, ProductServiceImpl object and injected the ProductRepositoryImpl object into the ProductService interface setter method.
Step 9: Let’s compile and run the application
mvn compile
mvn exec:java -Dexec.mainClass=com.mycompany.productstore.App
If there are no errors, we should see the list of products in the console.
When we are building the spring web applications, REST services we don’t explicitly include the spring-context jar, the other spring jars libraries includes it as a transitive dependency.