Spring Autowiring using Annotation – @Autowired, @Resource, @Qualifier, @Inject Annotation

Spring Autowiring by using the “autowire” attribute in the bean configuration file  we can wire all the properties of the bean class. Using Spring Autowiring through XML you cannot wire a particular property. In those cases we can use the Spring @Autowired annotation which allows auto-wiring of setter method, a constructor, a field, or even an arbitrary method.

Folder Structure:

  1. Create a new Java Project  SpringCoreTutorial” and create a package for our src files com.javainterviewpoint
  2. Add the required libraries to the build path. Java Build Path ->Libraries ->Add External JARs and add the below jars.

    commons-logging-1.2.jar
    spring-beans-4.2.4.RELEASE.jar
    spring-core-4.2.4.RELEASE.jar
    spring-context-4.2.4.RELEASE.jar
    spring-expression-4.2.4.RELEASE.jar

  3. Create the Java classes Employee.javaPermanentEmployee.java and EmployeeLogic.java under  com.javainterviewpoint folder.
  4. Place our configuration file SpringConfig.xml in the src directory

SpringConfig.xml

<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">
 
   <context:annotation-config></context:annotation-config>
 
   <bean id="emp" class="com.javainterviewpoint.Employee"></bean>
 
   <bean id="permemp" class="com.javainterviewpoint.PermanentEmployee"></bean>
</beans>
  • We have declared two beans one for our Employee class and and other for our PermanentEmployee class, we have not injected any reference to the property “pe” of our Employee class.

Spring AutoWiring @Autowired Annotation over Setter Method

@Autowired annotation can be applied to any particular property, in this Spring autowiring example lets autowire the setter method of the “pe” property with @Autowired annotation. Spring container will try to wire a bean which is compatible to type “PermanentEmployee”

Employee.java

Our Employee class has a property “pe” and we have added the @Autowire annotation over its setter method.

package com.javainterviewpoint;

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

public class Employee
{
    
    private PermanentEmployee pe;

    public Employee()
    {
        super();
    }
    public Employee(PermanentEmployee pe)
    {
        super();
        this.pe = pe;
    }
    
    public PermanentEmployee getPe()
    {
        return pe;
    }
    @Autowired
    public void setPe(PermanentEmployee pe)
    {
        this.pe = pe;
    }
}

PermanentEmployee.java

package com.javainterviewpoint;

public class PermanentEmployee
{
    private Employee employee;
    private int Salary;
    
    public PermanentEmployee()
    {
        super();
    }
    public PermanentEmployee(Employee employee, int salary)
    {
        super();
        this.employee = employee;
        Salary = salary;
    }
    
    public Employee getEmployee()
    {
        return employee;
    }
    public void setEmployee(Employee employee)
    {
        this.employee = employee;
    }
    public int getSalary()
    {
        return Salary;
    }
    public void setSalary(int salary)
    {
        Salary = salary;
    }
}

EmployeeLogic.java

package com.javainterviewpoint;

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

public class EmployeeLogic
{
    public static void main(String args[])
    {
        //Read the Configuration file using ApplicationContext
        ApplicationContext applicationContext = 
                new ClassPathXmlApplicationContext("SpringConfig.xml");
        //Get the Employee class instance
        Employee employee = (Employee)applicationContext.getBean("emp");
        //Print the PermanentEmployee details
        System.out.println("**** Employee Details ****");
        //Setting the salary 
        employee.getPe().setSalary(100);
        //Retrieving the Permanent Employee salary
        System.out.println(employee.getPe().getSalary());
    }
}
  • In our EmployeeLogic class we have read the Configuration file(SpringConfig.xml) and get all the bean definition through ApplicationContext
  • Get the Employee Class instance by calling the getBean() method over the context created.
  • Through the getPe() we will get the “PermanentEmployee” and using it we will be setting and retrieving the value of the salary property.

Output :

Upon running the EmployeeLogic class we will be getting the below output.

Spring Autowired Annotation Example

Spring @Autowired Annotation over Constructor

In addition to Setter method @Autowired annotation can be applied to the Constructor as well, spring will try to wire the bean compatible type of each Constructor argument. Here PermanentEmployee is the constructor argument, so the bean compatible to type PermanentEmployee will be injected.

package com.javainterviewpoint;

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

public class Employee
{
    
    private PermanentEmployee pe;

    public Employee()
    {
        super();
    }
    @Autowired
    public Employee(PermanentEmployee pe)
    {
        super();
        this.pe = pe;
    }
    
    public PermanentEmployee getPe()
    {
        return pe;
    }
    public void setPe(PermanentEmployee pe)
    {
        this.pe = pe;
    }
}

Spring @Autowired Annotation over array / collections

@Autowired annotation can also be applied to a property of array type or java collection. Lets say, if you annotate the property PermanentEmployee[] or List<PermanentEmployee> with @Autowired, Spring will auto-wire all the beans whose type is compatible with PermanentEmployee.

package com.javainterviewpoint;

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

public class Employee
{
    @Autowired
    private PermanentEmployee[] pe;

    public Employee()
    {
        super();
    }
    public Employee(PermanentEmployee pe)
    {
        super();
        this.pe = pe;
    }
    
    public PermanentEmployee getPe()
    {
        return pe;
    }
    public void setPe(PermanentEmployee pe)
    {
        this.pe = pe;
    }
}

required attribute @Autowired annotation

By default, all the properties with @Autowired are required. Whenever Spring can’t find a matching bean to wire, it will be throwing BeanCreationException.

BeanCreationException

But there will time when you want some property to be optional, then we can set the “required” attribute of @Autowired to false so if Spring cannot find the matching bean it will not be throwing exception.

package com.javainterviewpoint;

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

public class Employee
{
    
    private PermanentEmployee pe;

    public Employee()
    {
        super();
    }
    public Employee(PermanentEmployee pe)
    {
        super();
        this.pe = pe;
    }
    
    public PermanentEmployee getPe()
    {
        return pe;
    }
    @Autowired(required = false)
    public void setPe(PermanentEmployee pe)
    {
        this.pe = pe;
    }
}

Use of @Qualifier annotation Spring – AutoWiring byName

Autowiring byType will not work when there is more than one bean of same type declared. We will be getting BeanCreationException / NoUniqueBeanDefinitionException Exception

 Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void com.javainterviewpoint.Employee.setPe(com.javainterviewpoint.PermanentEmployee); nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.javainterviewpoint.PermanentEmployee] is defined: expected single matching bean but found 2: permemp1,permemp2
 at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:661)
 at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
 at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
 ... 13 more
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.javainterviewpoint.PermanentEmployee] is defined: expected single matching bean but found 2: permemp1,permemp2
 at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1126)
 at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014)
 at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:618)
 ... 15 more

Spring AutoWiring has the solution for it, we can use the @Qualifier annotation by providing the name of the required bean.

Our configuration file will be like below

<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">
 
   <context:annotation-config></context:annotation-config>
 
   <bean id="emp" class="com.javainterviewpoint.Employee"></bean>
 
   <bean id="permemp" class="com.javainterviewpoint.PermanentEmployee"></bean>
   <bean id="permemp2" class="com.javainterviewpoint.PermanentEmployee"></bean>
</beans>

Now we can use the @Qualifier annotation to select the required property type. Now our Employee class will be re-written like below

package com.javainterviewpoint;

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

public class Employee
{
    
    private PermanentEmployee pe;

    public Employee()
    {
        super();
    }
   
    public Employee(PermanentEmployee pe)
    {
        super();
        this.pe = pe;
    }
    
    public PermanentEmployee getPe()
    {
        return pe;
    }
    @Autowired
    @Qualifier("permemp2")
    public void setPe(PermanentEmployee pe)
    {
        this.pe = pe;
    }
}

Spring @Resource annotation

When ever you want to implement Spring autowiring byName using annotation, you can annotate a setter method, a constructor, or a field with @Resource annotation which is based on JSR-250. Spring will attempt to find if any bean is declared in the configuration file with property name. You can also specify the bean name explicitly using the name attribute.

<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">
 
   <context:annotation-config></context:annotation-config>
 
   <bean id="emp" class="com.javainterviewpoint.Employee"></bean>
 
  <bean id="pe" class="com.javainterviewpoint.PermanentEmployee"></bean>
   <bean id="permemp2" class="com.javainterviewpoint.PermanentEmployee"></bean>
</beans>

Now we can use the @Qualifier annotation to select the required property type. Now our Employee class will be re-written like below

package com.javainterviewpoint;

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

public class Employee
{
    
    private PermanentEmployee pe;

    public Employee()
    {
        super();
    }
   
    public Employee(PermanentEmployee pe)
    {
        super();
        this.pe = pe;
    }
    
    public PermanentEmployee getPe()
    {
        return pe;
    }
    @Resource(name="pe")
    public void setPe(PermanentEmployee pe)
    {
        this.pe = pe;
    }
}

@Inject annotation Spring

Spring 3.0 supports JSR 330 standard : Dependency Injection for Java. In Spring 3 application, we can use @Inject instead of Spring’s @Autowired to inject a bean. The JSR 330 Standard @Inject annotation works exactly the same like Spring’s @Autowired annotation. In order to use @Inject annotation we need to add “javax.inject-1.jar” into our project.

package com.javainterviewpoint;

import javax.inject.Inject;

public class Employee
{
    
    private PermanentEmployee pe;

    public Employee()
    {
        super();
    }
   
    public Employee(PermanentEmployee pe)
    {
        super();
        this.pe = pe;
    }
    
    public PermanentEmployee getPe()
    {
        return pe;
    }
   @Inject
    public void setPe(PermanentEmployee pe)
    {
        this.pe = pe;
    }
}

Pitfalls of @Inject over @Autowired

  1. @Inject annotation doesn’t have the required attribute unlike @Autowired annotation, so that we can make a filed mandatory or optional.
  2. JSR 330 @Inject annotation is Singleton by default. But in Spring we can use other scopes as well using the @Scopes annotation.

Difference Between @Resource, @Autowired and @Inject in Spring Injection

Leave a Reply

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