Let’s look at the examples to Autowire the Spring beans by constructor, by type and by their names using Spring XML configuration.
Class Structure
Product
– a POJO class to store product infoProductDAO
– an interface that we will use in a dependent service classProductDAOImpl
– an implementation ofProductDAO
returns list of mocked Product instancesProductService
– an interface that we will use in the application to hold a service instanceProductServiceImpl
– an implementation ofProductService
and the dependent ofProductDAO
instanceApplication
– It will get theProductService
instance to fetch products
Creation of Maven Project
First create a simple Maven project by skipping archtype selection in STS.
Add below pom.xml
file which can be found at the root of the project.
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.techstackjournal</groupId>
<artifactId>xml-config-autowire</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
Right click on the project, and select Maven=>Update Project. This will download all the required jar files for the application.
Creating the Model Class
Let’s create a Product
model class which will hold the instances returned by the DAO layer.
package com.techstackjournal.model;
public class Product {
private String productId;
private String productName;
private double price;
public Product() {
}
public Product(String productId, String productName, double price) {
super();
this.productId = productId;
this.productName = productName;
this.price = price;
}
public String getProductId() {
return productId;
}
public void setProductId(String productId) {
this.productId = productId;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() {
return "Product [productId=" + productId + ", productName=" + productName + ", price=" + price + "]";
}
}
Data Access Layer
In this layer, we’ll create ProductDAO
interface, which will be implemented by ProductDAOImpl
. Also, ProductServiceImpl
will use ProductDAO
interface to call the findAll
method. We call this approach as coding to interface. With this approach, we can decrease the dependence on the implementation class.
package com.techstackjournal.dao;
import java.util.List;
import com.techstackjournal.model.Product;
public interface ProductDAO {
List<Product> findAll();
}
ProductDAOImpl
implements ProductDAO
and provides a findAll
method. In this findAll
method, we are not writing the actual data access logic to simplify the subject in focus. We’ll just mock the findAll
method by returning a collection object.
package com.techstackjournal.dao;
import java.util.ArrayList;
import java.util.List;
import com.techstackjournal.model.Product;
public class ProductDAOImpl implements ProductDAO {
public List<Product> findAll() {
List<Product> products = new ArrayList<Product>();
products.add(new Product("1", "Mobile", 400));
products.add(new Product("2", "Book", 10));
return products;
}
}
Service Layer
In this Service Layer, we’ll be creating ProductService interface and ProductServiceImpl class.
package com.techstackjournal.service;
import java.util.List;
import com.techstackjournal.model.Product;
public interface ProductService {
List<Product> findAll();
}
ProductServiceImpl
implements ProductService
interface. This class is in HAS-A relation with an object of type ProductDAO
. But you can see that we are not creating any instance of type ProductDAO
. Spring Container will wire the instance of ProductServiceImpl
with the instance of type ProductDAO
either by constructor or by type ProductDAO
or by the name of the reference variable productDao
.
package com.techstackjournal.service;
import java.util.List;
import com.techstackjournal.dao.ProductDAO;
import com.techstackjournal.model.Product;
public class ProductServiceImpl implements ProductService {
private ProductDAO productDao;
public ProductServiceImpl() {
}
public ProductServiceImpl(ProductDAO productDao) {
super();
this.productDao = productDao;
}
public List<Product> findAll() {
return productDao.findAll();
}
public void setProductDao(ProductDAO productDao) {
this.productDao = productDao;
}
}
Main Application
In this class, we’ll be fetching the ProductService
instance from Spring Container using ClassPathXmlApplicationContext
.
package com.techstackjournal.app;
import java.util.List;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.techstackjournal.model.Product;
import com.techstackjournal.service.ProductService;
public class Application {
public static void main(String[] args) {
ApplicationContext appContext = new ClassPathXmlApplicationContext("appContext.xml");
ProductService service = appContext.getBean("productService", ProductService.class);
List<Product> products = service.findAll();
for (Product product : products) {
System.out.println(product);
}
}
}
Spring Application Context XML
Finally, in this appContext.xml
file we’ll define 2 beans to get the instances of type ProductDAOImpl
and ProductServiceImpl
, respectively.
The location of the file should be under src/main/resources
directory.
Autowire by Constructor
By defining the autowire
attribute with value constructor
, we can instruct Spring Container to inject ProductDAOImpl
instance into ProductServiceImpl
via its constructor.
<?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.xsd">
<bean name="productDao"
class="com.techstackjournal.dao.ProductDAOImpl" />
<bean name="productService"
class="com.techstackjournal.service.ProductServiceImpl" autowire="constructor" />
</beans>
Autowire by Type
To instruct Spring Container to wire the beans by type, we initialize the autowire attribute with byType
. This will match the available bean types in Spring context with the dependency requirements in ProductServiceImpl
and wires them together automatically.
<bean name="productService"
class="com.techstackjournal.service.ProductServiceImpl" autowire="byType" />
Autowire by Name
To instruct Spring container to wire the beans by names of the reference variables, we initialize the attribute autowire
with byName
value.
<bean name="productService"
class="com.techstackjournal.service.ProductServiceImpl" autowire="byName" />