Spring Framework: @Autowired , @Inject and @Resource

What the purpose of @Autowired in spring? Where it can be applied?

@Autowired annotation tells the spring to auto-wire/inject the relevant bean(s) and its collaborators/dependencies with Spring IOC container. (with the support of Spring Dependency Injection)

There are three places where you can use @Autowired to auto-wire a bean. Those are on the setter method, constructor or a field.

The @Autowired annotation tells Spring where an injection needs to occur. If you put it on a method “setMovieFinder” it understands (by the prefix set + the @Autowired annotation) that a bean needs to be injected. In the second scan, Spring searches for a bean of type “MovieFinder”, and if it finds such bean, it injects it to this method. If it finds two such beans you will get an Exception. To avoid the Exception, the @Qualifier annotation can be used.

 

 What is the purpose of @Autowired “required” attribute?

If @Autowired(required=true) , the Spring must autowire the relevant bean. If there is no matching bean to wire, Spring will throw an exception. To avoid this exception we can disable this checking feature by setting the required attribute of @Autowired to false. In that case, if Spring does not find a matching bean, it will leave the property as unset.

 

What are the different ways to autowire a spring bean?

There are different ways through which we can autowire a spring bean.

  1. autowire byName (setter)
  2. autowire byType  (property)
  3. autowire by constructor (constructor)

The @Autowired annotation can be applied to only one of the constructor methods. If you apply the annotation to more than one constructor method, Spring will complain during bootstrapping ApplicationContext.

 

What is the difference between @Autowired , @Resource and @Inject?

Instead of @Autowired, you can also use @Resource(name=”messageProvider”) to achieve the same result.@Resource is one of the annotations in the JSR-250 standard that defines a common set of Java annotations for use on both JSE and JEE platforms. Different from @Autowired, the @Resource annotation supports the name parameter for more fine-grained DI requirements.(But same thing can be achieved using @Qualifier annotation along with @Autowired)

Additionally, Spring supports use of the @Inject annotation introduced as part of JSR-330, “Contexts and Dependency Injection for the Java EE Platform” (CDI). @Inject is equivalent in behavior to Spring’s @Autowired annotation.

  1. @Resource – Defined in the javax.annotation package and part of Java (JSR 250)
  2. @Inject – Defined in the javax.inject package and part of Java (JSR 330)
  3. @Autowired – Defined in the package org.springframework.bean.factory and part of Spring framework.

 

 What is the purpose of @Qualifier annotation in Spring?

Spring provides the @Qualifier annotation, which allows more fine-grained control for Spring to perform autowiring of dependencies based on qualifier name. There may be scenarios when we create more than one bean of the same type and want to wire only one of them based on the name (bean identifier). This can be controlled using the @Qualifier annotation along with the @Autowired annotation. If you try to autowire a bean without the @Qualifier (“beanIdentifier”), the spring will throw an exception to indicate that it has found ‘X’ number of beans for the given type and confused with selecting the most appropriate bean out of them.

@Qualifier annotation can be applied for setter methods, fields and constructors with arguments.

Ok. Enough theory! lets look at the coding example. The complete code can be found at GitHub.  Click here to Download.

 

Here is the project structure.

Screen Shot 2017-09-18 at 10.40.54 PM

 

Here is the project dependency requirement. (pom.xml)

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>javax.inject</groupId>
            <artifactId>javax.inject</artifactId>
            <version>1</version>
        </dependency>
    </dependencies>

@Inject annotation is available in javax.inject package and we need to explicitly add that dependency for our project.

Here are the sample service classes.

SampleService.java

@Service
public class SampleService
{
    public String getMessage(String annotation)
    {
        return "This method is called using a bean inject with " +annotation;
    }
}

 

EmployeeService.java

public class EmployeeService
{
   //TODO implementation should goes here
}

 

ContractEmployeeService.java

@Service("contractEmployeeService")
public class ContractEmployeeService extends EmployeeService
{
   //TODO implementation should goes here
}

 

PermanentEmployeeService.java

@Service("permanentEmployeeService")
public class PermanentEmployeeService extends EmployeeService
{
   //TODO implementation should goes here
}

 

You can see that there are two service implementations for the EmployeeService.

 

SampleRestApiController.java

@RestController
public class SampleRestApiController {

    @Autowired
    private SampleService sampleService1;

    @Resource
    private SampleService sampleService2;

    @Inject
    private SampleService sampleService3;

    @Autowired
    @Qualifier("permanentEmployeeService")
    private EmployeeService employeeService;

    @GetMapping("/autowired")
    public String invokeAutowiredExample() {
        return sampleService1.getMessage("@Autowired");
    }

    @GetMapping("/resource")
    public String invokeResourceExample() {
        return sampleService2.getMessage("@Resource");
    }

    @GetMapping("/inject")
    public String invokeInjectExample() {
        return sampleService3.getMessage("@Inject");
    }
}

 

In SampleRestApiController, you can see that three different dependency injection annotations have been used to inject dependencies for the member variables.  Following will be the output of each REST api call.

GET    /autowired

Screen Shot 2017-09-18 at 11.07.31 PM

 

GET    /resource

Screen Shot 2017-09-18 at 11.08.03 PM

 

GET    /inject

Screen Shot 2017-09-18 at 11.08.37 PM

 

Why @Qualifier annotation is used?

 

You can see that there are two implementations of the EmployeeService class. Both of these implementation classes have been annotated with @Service method. Therefore, there will be two bean instances will be available in the Spring IOC Container. If you try to inject the dependency for the employeeService instance,  the spring will be in a trouble of selecting the most appropriate bean out of those two bean instances.

@Autowired
private EmployeeService employeeService;

Since the spring can’t determine the most suitable implementation for the dependency injection, it will throw the following Exception.

 No qualifying bean of type 
'com.springbootdev.autowiring.example.service.EmployeeService' 
available: expected single matching bean but found 2:

 

Therefore, in order to avoid such exceptions we can use the @Qualifier annotation to declare the most appropriate/qualified dependency out of available implementaions.

@Autowired
@Qualifier("permanentEmployeeService")
private EmployeeService employeeService;

 

Here the EmploymentService will be initialized and injected with the bean “permanentEmploementService” available in Spring IOC container.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s