Autowiring using Annotation in Spring

In the previous article, we started with an Annotation-based configuration. In this article, we will go one step ahead and learn another annotation @Autowire in the Spring framework.

Initialization of object is done by Spring container using beans.xml file i.e the config file. Autowiring resolves the dependency of the inner bean or collaborating beans automatically. To know more about Autowiring using XML-based configuration check this article What is Autowiring in Spring?

@Autowired Annotations

@Autowired annotation is used to implement the feature of Autowirng in Spring Framework.

  • It injects the dependency into the inner beans or collaborating beans.
  • It is done by using two modes: byType & byName.
  • Internally, Spring checks using byName mode if the name is matched it would inject the dependencies otherwise it would go for byType mode.

@Autowirng annotation is applied to the following:

  • on the property(dependencies)
  • on the setter method
  • on constructor

To enable annotation wiring in Spring Container, First, we have to enable the annotation-based configuration inside the configuration file like the following.

<?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-3.0.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- To activate annotation in spring -->
    <context:annotation-config />
</beans>

There is also one more way, in which we can activate the annotation-based configuration by specifying the bean definition of AutowiredAnnotationBeanPostProcessor class in the config file.

<?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-3.0.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.0.xsd">
 <!-- To activate the annotation in spring -->
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"></bean>
</beans>

Example of @Autowired annotation

In this example, we will create a class Department that has a reference of Employee class.

Create a Spring Project Go to File> New > Other > Search maven > Select Maven Project > Next > Search Filter org.apche.maven.archetypes/webapp > Next > Enter Group Id & Archetype id > Finish.

Department.java

  • In this class, use the @Autowired on the dependency Employee employee.
package com.codedec.di;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

public class Department {
  @Autowired
  private Employee employee;
  private String deptName;

  public void setEmployee(Employee employee) {
    this.employee = employee;
  }

  public String getDeptName() {
    return deptName;
  }

  public void setDeptName(String deptName) {
    this.deptName = deptName;
  }

  public void show() {
    System.out.println("Department Name: " + deptName + "\nEmployee Info " + employee);
  }
}

Employee.java

package com.codedec.di;

public class Employee {

  private String empName;
  private int empId;
  public void setEmpName(String empName) {
    this.empName = empName;
  }
  public void setEmpId(int empId) {
    this.empId = empId;
  }
  @Override
  public String toString() {
    return "Employee [empName=" + empName + ", empId=" + empId + "]";
  }
  
  
}

beans.xml 

  • Now, we will create a beans.xml file and will inject the dependencies.
  • Use the <property> element to set the values.
  • Here, It will automatically auto-wire using the @Autowire annotation that we have applied to the Department class.
  • On line No: 11 , we have used <context:annotation-config /> to enable annotation in spring.
<?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.xsd">


  <!-- Used to activate the @Autowired annotation in Spring -->
  <context:annotation-config />

  <bean id="e1" class="com.codedec.di.Employee">
    <property name="empName" value="Nicolas"></property>
    <property name="empId" value="102"></property>
  </bean>

  <bean id="dept" class="com.codedec.di.Department">
    <property name="deptName" value="Infromation Technology"></property>
  </bean>

</beans>

App.java

  • Create an App.java and create the Object of Application Context, get the bean from it and call the show() method.
package com.codedec.di;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {

  public static void main(String[] args) {
    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    Department d = context.getBean("dept",Department.class);
     d.show();
  }
}

Output

Department Name: Infromation Technology
Employee Info Employee [empName=Nicolas, empId=102]

Thus, using @Autowiring annotation on the property, Spring Injects the dependencies.

Now, Consider one more Object of Employee is created and dependencies are set using the property in the beans.xml file in the following ways:

<?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.xsd">


  <!-- Used to activate the @Autowired annotation in Spring -->
  <context:annotation-config />

  <bean id="e1" class="com.codedec.di.Employee">
    <property name="empName" value="Nicolas"></property>
    <property name="empId" value="102"></property>
  </bean>
  <bean id="e2" class="com.codedec.di.Employee">
    <property name="empName" value="John"></property>
    <property name="empId" value="103"></property>
  </bean>
  <bean id="dept" class="com.codedec.di.Department">
    <property name="deptName" value="Infromation Technology"></property>
  </bean>
  
</beans>

Now, once again run your application. It would throw the following error

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.codedec.di.Employee' available: expected single matching bean but found 2: e1,e2
  at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:220)
  at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1358)
  at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300)
  at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:657)
  ... 16 more

Here, the Exception is NoUniqueBeanDefinitionException means it is not able to resolve the objects. So, this will be solved by @Qualifier annotation.

What is @Qualifier Annotation?

When the beans of the same class are not resolved by using Autowiring byType mode Spring would not understand which dependencies to inject so this is resolved by @Qualifier annotation.

Let’s modify the above example. Just add @Qualifier annotation above the property and pass the id of the bean in the Department.java file.

package com.codedec.di;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

public class Department {

  @Autowired
  @Qualifier("e2")
  private Employee employee;
  private String deptName;

  public void setEmployee(Employee employee) {
    this.employee = employee;
  }

  public String getDeptName() {
    return deptName;
  }

  public void setDeptName(String deptName) {
    this.deptName = deptName;
  }

  public void show() {
    System.out.println("Department Name: " + deptName + "\nEmployee Info " + employee);
  }
}

beans.xml file

  • Just added another bean
<?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.xsd">


  <!-- Used to activate the @Autowired annotation in Spring -->
  <context:annotation-config />

  <bean id="e1" class="com.codedec.di.Employee">
    <property name="empName" value="Nicolas"></property>
    <property name="empId" value="102"></property>
  </bean>
  <bean id="e2" class="com.codedec.di.Employee">
    <property name="empName" value="John"></property>
    <property name="empId" value="103"></property>
  </bean>
  <bean id="dept" class="com.codedec.di.Department">
    <property name="deptName" value="Infromation Technology"></property>
  </bean>
  
</beans>

Output

Department Name: Infromation Technology
Employee Info Employee [empName=John, empId=103]

Now, we can see the @Qualifier annotation helps us to resolve which bean to be autowired.

Thus, this was all about how to use @Autowired annotation and @Qualifier annotation. In the next article of this tutorial, we will see @Component and @Value annotation.