Categories
Spring Spring Core

Auto-wiring with Example

In Spring you can Inject Dependencies either in the form of XML or Annotation or Java Code. In this Article we are going to look at how Injection made possible using Autowired annotation and different possible types of Autowiring in Spring with working examples.

Auto-wiring in Spring Types

  1. Autowiring by Constructor
  2. Autowiring by Setter-Method
  3. Autowiring by Methods
  4. Autowiring by Method with Multiple Arguments
  5. Autowiring by Variables/Identifiers
  6. Mixing Autowiring with Variables, Constructor and Methods

Autowiring by Constructor

	package net.geekcoders.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import net.geekcoders.service.EmployeeService;
public class EmployeeController {	
	@Autowired
	public EmployeeController(EmployeeService employeeService) {
		this.employeeService = employeeService;
	}	
}
  • You can Provide @Autowired annotation in Constructor if you provide Arguments with Specific Types. 
  • In the above example, Spring will search for the Bean with Type EmployeeService in a IoC Container and Inject the bean into the Controller class.

Autowiring by Setter Method

You can provide @Autowired in Setter-Method as shown below.

package net.geekcoders.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import net.geekcoders.service.EmployeeService;
public class EmployeeController {	
	private EmployeeService employeeService;
	public void addNewEmployee() {
		this.getEmployeeService().addNewEmployee();
	}
	/**
	 * @return the employeeService
	 */
	public EmployeeService getEmployeeService() {
		return employeeService;
	}
	/**
	 * @param employeeService the employeeService to set
	 */
	@Autowired
	public void setEmployeeService(EmployeeService employeeService) {
		this.employeeService = employeeService;
	}
}

As I stated above, Spring will search for the Type of the Argument mentioned in the setter-method parameter in IoC Container and Inject as a Dependency.

Autowiring by Methods

@Autowired
	public void addNewEmployee(EmployeeService employeeService) {
		employeeService.addNewEmployee();
	}
  • You can provide autowired annotation in method parameters also. 
  • This will be treated the same as Setter-Method Injection.

Autowiring by Methods with Multiple Arguments

	@Autowired
	public void addNewEmployee(EmployeeService employeeService, Employee employee) {
		employeeService.addNewEmployee(employee);
	}
  • Spring will search for EmployeeService Type Bean and Employee Type Bean in IoC Container and Inject here.
  • If any of the Bean is not found in Container, then it will throw an exception. 

Autowiring by Variables/Identifiers

package net.geekcoders.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import net.geekcoders.service.EmployeeService;
public class EmployeeController {	
	@Autowired
	private EmployeeService employeeService;
	public EmployeeController(EmployeeService employeeService) {
		this.employeeService = employeeService;
	}
	public void addNewEmployee() {
		this.getEmployeeService().addNewEmployee();
	}
	/**
	 * @return the employeeService
	 */
	public EmployeeService getEmployeeService() {
		return employeeService;
	}
	/**
	 * @param employeeService the employeeService to set
	 */
	public void setEmployeeService(EmployeeService employeeService) {
		this.employeeService = employeeService;
	}
}

You can provide @Autowired annotation in Variable also.

Mixing Autowiring with Variables, Constructor and Methods

  • Autowiring annotation can be provided in Variable, Method, Setter-Method and Constructor at the same time.
  • This will be useful if you have more than one Dependency for a Bean.

Key Terms

  • Spring will always look at the Type of the Bean when using Autowiring to Inject the requested Dependency. 
  • If you are using only one Constructor in a Bean, then you don’t need to provide @Autowired. Because the container will automatically take the required dependency. 
  • You can provide required=”false” if this is not a mandatory dependency. 
  • If there is no Bean found in the container then Spring will be left blank, otherwise it will throw an exception.
@Autowired(required = false)
	public void setEmployeeService(EmployeeService employeeService) {
		this.employeeService = employeeService;
	}
  • Always use Mandatory dependency in Constructor arguments and optional dependency in Setter-Method for better code readability. 
  • Autowiring using Constructor, Variable/Identifier and Setter-Method is advisable. 
  • Spring will always search for the Type you mentioned in Arguments or Variable. So, make sure to provide the correct type in Variable and Arguments. If not found “no type match found” error will be thrown at runtime. 
  • You can also provide Autowiring for an Array or Collection as shown below.
@Autowired
	public void setEmployeeService(List<Employee> employees) {
		this.employeeList = employees;
	}
  • If you have more than one constructor defined in a Bean, then you can use default @Autowired annotation in only one Constructor and all other constructor should be defined as @Autowired(required=false)
  • You can also use @Autowired for Spring API’s Interfaces. Ex., BeanFactory, ApplicationContext, ResourceLoader, MessageSource,…
public class EmployeeController {	
   @Autowired
    private ApplicationContext context;
    // ...
}
  • All the Autowired Bean names should be explicitly configured using XML Configuration or Java Based @Bean configuration.
  • As you are using Annotation based wiring, you need to mention <context:annotation-config /> in XML Configuration. Otherwise, Container won’t search for Autowired annotated bean in Container and Inject as Dependency.

Autowired Example

For the below example, I have used the Autowired by Constructor method. You can change it to Variables/Identifiers or Setter-Method as mentioned above. 

Step 1 : pom.xml

Create a Maven Project and add below mentioned dependencies in the pom.xml file.

<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>5.2.6.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>5.2.6.RELEASE</version>
		</dependency>
	</dependencies>

Step 2 : Controller Class

Create controller under “net.geekcoders.controllers” package and copy below code.

package net.geekcoders.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import net.geekcoders.service.EmployeeService;
public class EmployeeController {	
	private EmployeeService employeeService;
	
	@Autowired
	public EmployeeController(EmployeeService employeeService) {
		this.employeeService = employeeService;
	}
	public void addNewEmployee() {
		this.getEmployeeService().addNewEmployee();
	}
	/**
	 * @return the employeeService
	 */
	public EmployeeService getEmployeeService() {
		return employeeService;
	}
	/**
	 * @param employeeService the employeeService to set
	 */
	public void setEmployeeService(EmployeeService employeeService) {
		this.employeeService = employeeService;
	}
}
  • As you see the above example, Spring will search for the EmployeeService typed Bean configured in the Container. If found it will inject into the Constructor args. 
  • What if we have more than one implementation class for the EmployeeService interface?
  • In this case container cannot decide which implementation has to inject here in this constructor and throws an exception as conflict. We can resolve this conflict using @Qualifier annotation. Read this post to know more about Qualifiers in Spring

Step 3 : Interface

Create an Interface called “EmployeeService” under “net.geekcoders.service” package and copy below code.

package net.geekcoders.service;
import net.geekcoders.Employee;
public interface EmployeeService {
	void addNewEmployee();
	int getEmployees();
	
	boolean modifyEmployee(Employee emp);
}

Step 4 : Implementation Class

Create an implementation class for the EmployeeService interface as like below.

package net.geekcoders.service;
import net.geekcoders.Employee;
public class permanentEmployeeSerivceImpl implements EmployeeService {
	@Override
	public void addNewEmployee() {
		System.out.println("permanentEmployeeServiceImpl : addNewEmployee");
	}
	@Override
	public int getEmployees() {
		System.out.println("permanentEmployeeServiceImpl : getEmployees");
		return 0;
	}
	@Override
	public boolean modifyEmployee(Employee emp) {
		System.out.println("permanentEmployeeServiceImpl : modifyEmployee");
		return false;
	}
}

Step 5 : Employee Pojo

Create Employee Pojo class to store employee details and processed by service implementation in Step 4.

package net.geekcoders;
public class Employee {
	private String empName;
	private int age;
	/**
	 * @return the empName
	 */
	public String getEmpName() {
		return empName;
	}
	/**
	 * @param empName the empName to set
	 */
	public void setEmpName(String empName) {
		this.empName = empName;
	}
	/**
	 * @return the age
	 */
	public int getAge() {
		return age;
	}
	/**
	 * @param age the age to set
	 */
	public void setAge(int age) {
		this.age = age;
	}
}

Step 6 : Bean Definition

For Annotation based configurations, we have to configure Bean’s using XML Based Container Configuration or using @Bean in Java Based Configuration. 

It is recommended for managing the code using XML and Annotation combinations. So, I’m creating an applicationContext.xml file in the src folder and defining the dependencies as below.

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
	<context:annotation-config />
	<bean id="employeeController" class="net.geekcoders.controllers.EmployeeController"/>
	<bean id="permanentEmployeeService" class="net.geekcoders.service.permanentEmployeeSerivceImpl"/>
	
</beans>

It is mandatory to define <context:annotation-config /> in XML configuration to intimate Spring that we are using Annotations. Otherwise, Spring won’t search for Annotated Bean in Container and throws an exception in runtime.

Step 7 : Starter Class

Create EmployeeStarter class as below and configure ApplicationContext. As this is a Spring Core application, we need at least one main class in a project to startup.

package net.geekcoders;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import net.geekcoders.controllers.EmployeeController;
public class EmployeeStarter {
	public static void main(String[] args) {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		EmployeeController controller = applicationContext.getBean("employeeController", EmployeeController.class);
		controller.addNewEmployee();
	}
}

After completing all the mentioned steps, your project structure will be like below.

Now run the application from EmployeeStarter class and you can see the EmployeeServiceImpl Bean has injected into the Constructor of EmployeeController class using @Autowiring annotation and prints below log in console.

That’s all on Autowiring in Spring with an example for now!!!

Happy Reading!!!

5 replies on “Auto-wiring with Example”

Leave a Reply

Your email address will not be published. Required fields are marked *