In this article, we will walk through an example demonstrating ‘constructor’ autowiring mode. This is actually ‘byType’ with constructor argument i.e.; if the data type of the bean is same with other bean constructor argument then it will autowire it.
When attribute autowire=“constructor” is set in the <bean> element, then at runtime Spring injects the collaborating beans by inspecting the other beans defined in the configuration file with the compatible data type in constructor argument.
Note: If there is no one exact constructor, then it does nothing and ‘null’ value gets injected. Further using this object throws ‘NullPointerException’.
We will see a detailed example and its explanation below.
Technology Used
- Java 1.7
- Eclipse Kepler IDE
- Maven 3.0.4
- Spring-4.0.0-RELEASE
Mavenize or download required jars
Add Spring-4.0.0 dependencies to the pom.xml
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency>
Folks who aren’t familiar with Maven concepts or don’t require maven for their project, can download the below jars individually from the spring site and include them in the classpath
- spring-core-4.0.0-RELEASE
- spring-context-4.0.0-RELEASE
- spring-beans-4.0.0-RELEASE
- spring-aop-4.0.0-RELEASE
- spring-expression-4.0.0-RELEASE
- commons-logging-1.1.1
- aopalliance-1.0
Let’s see coding in action
Create simple Spring beans Address and Employee
Address class
Simple & straight forward spring beans with four primitive properties and its getter/setters with one public method called “printAddressDetail()” to print the address details.
Address.java
package com.spring.series.auto.wiring; public class Address { private String street; private String city; private String state; private String zipcode; /** * getter's and setter's */ public String getStreet() { return street; } public void setStreet(String street) { this.street = street; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getState() { return state; } public void setState(String state) { this.state = state; } public String getZipcode() { return zipcode; } public void setZipcode(String zipcode) { this.zipcode = zipcode; } /** * This method prints the address details */ public void printAddressDetail(){ System.out.println("Address Street \t\t: " + street); System.out.println("Address City \t\t: " + city); System.out.println("Address State \t\t: " + state); System.out.println("Address Zip Code \t: " + zipcode); } }
Employee.java
Spring bean with four primitive properties and one complex property named “address” and its getter/setters with one public method called “printEmployeeDetail()” to print the employee details.
Also, there is one-argument constructor with ‘address’ member variable
Note: With autowire=’constructor’ set there is no need of setter/getter for ‘address’ property of employee bean, but it’s still a good practice to keep setter/getter
package com.spring.series.auto.wiring; public class Employee { private String name; private int age; private String employeeCode; private String designation; private Address address; /** * * one argument constructor with address variable * @param address */ public Employee(Address address) { super(); this.address = address; } /** * getter's and setter's */ public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getEmployeeCode() { return employeeCode; } public void setEmployeeCode(String employeeCode) { this.employeeCode = employeeCode; } public String getDesignation() { return designation; } public void setDesignation(String designation) { this.designation = designation; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } /** * This method prints the employee details */ public void printEmployeeDetail(){ System.out.println("Employee Name \t\t: " + name); System.out.println("Employee Age \t\t: " + age); System.out.println("Employee Code \t\t: " + employeeCode); System.out.println("Employee Designation \t: " + designation); System.out.println("\nInvoking Address object & Printing Address details\n"); // this loc invokes method of Address class & this object is injected during spring bean instantiation address.printAddressDetail(); } }
Create Spring Bean Configuration file (Spring XML)
In this Spring Context XML, constructor property ‘address’ not set or wired explicitly with any other beans in the configuration file. With autowire=’constructor’ set, container inspects compatible data type and injects it.
SpringContext.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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- employee bean definition goes here --> <bean id="employee" class="com.spring.series.auto.wiring.Employee" autowire="constructor"> <property name="name" value="Mark" /> <property name="age" value="32" /> <property name="employeeCode" value="E10910" /> <property name="designation" value="Software Architect" /> </bean> <!-- address bean definition goes here --> <bean id="address" class="com.spring.series.auto.wiring.Address"> <property name="street" value="Spring Office St." /> <property name="city" value="Columbus" /> <property name="state" value="OHIO" /> <property name="zipcode" value="43211" /> </bean> </beans>
Note: Name of the Spring Bean Configuration file can be anything (not necessary to have SpringContext.xml) and it’s your choice. But, in the enterprise application keep these file names appropriate to the business context. So that it will increase the readability of the application.
Project Structure in Eclipse (Package Explorer view)
Test the Application that’s exactly …. Run it!
Let’s test using ApplicationContext
TestEmployee.java
package com.spring.series.auto.wiring; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestEmployee { public static void main(String[] args) { testAutoWiring(); } private static void testAutoWiring(){ ApplicationContext applicationContext = new ClassPathXmlApplicationContext("com/spring/series/auto/wiring/SpringContext.xml"); Employee employee = (Employee) applicationContext.getBean("employee"); System.out.println("Spring Autowiring using constructor mode \n"); // invoke print() method of Employee class employee.printEmployeeDetail(); } }
Output in console
Spring Autowiring using constructor mode Employee Name : Mark Employee Age : 32 Employee Code : E10910 Employee Designation : Software Architect Invoking Address object & Printing Address details Address Street : Spring Office St. Address City : Columbus Address State : OHIO Address Zip Code : 43211
In the coming articles, we will see examples based on Annotation autowiring
Download project
Spring Autowiring using constructor (3kB)
Happy Coding !!
Happy Learning !!