Autowired in Spring Boot

                                 Autowired in Spring Boot


Keyword : @Autowired

  1. byName
  2. byType
  3. constructor
  4. setter
  5. @Qualifier
  6. Custom Qualifier annotation
  7. @Primary
  8. JSR-250 Annotation : @Resource
  9. JSR-330 Annotation : @Inject
Dependancies : web , lombok , 
## byType :

It basically check the type . If the type is matched with service then it automatically create the bean.

CarController.java
package com.vrushant.AutowiredInSpringBoot.controller;
@RestController
@RequestMapping("/cars")
public class CarController {
@Autowired
private Car car; // By Type
@GetMapping
public String drive(){
return car.drive();
}
}
Car.java

interface
package com.vrushant.AutowiredInSpringBoot;

public interface Car {
String drive();
}
SedanCar.java

Service
package com.vrushant.AutowiredInSpringBoot;
import org.springframework.stereotype.Service;
@Service
public class SedanCar implements Car{
@Override
public String drive(){
return "Driving Sedan Car";
}
}

Only one service can be used in byType autowired , like if we create another service named "SuvCar.java" then spring will be confused which one to used . 
package com.vrushant.AutowiredInSpringBoot;
import org.springframework.stereotype.Service;
@Service
public class SuvCar implements Car{
@Override
public String drive(){
return "Driving SUV Car";
}
}
To Solve this problem we can use @Qualifier or ByName .

### byName

CarController.java
@RestController
@RequestMapping("/cars")
public class CarController {
@Autowired
private Car sedanCar; // By Name
@GetMapping
public String drive(){
return sedanCar.drive();
}
}
Note : All other codes will same as above code in ByType.

In ByName , we have to specify the name of the service class (  sedanCar  in this case ) and spring will create the bean of that service class.

### Primary

CarController.java
@RestController
@RequestMapping("/cars")
public class CarController {
@Autowired
private Car car;
@GetMapping
public String drive(){
return car.drive();
}
}
we have 2 beans named sedanCar and SuvCar . So controller is confused which one to call . So solve this problem we can make one bean / service as primary so that controller will give priority to it.

SedanCar.java
@Primary
@Service
public class SedanCar implements Car{
@Override
public String drive(){
return "Driving Sedan Car";
}
}
SuvCar.java
@Service
public class SuvCar implements Car{
@Override
public String drive(){
return "SUV Car Driving";
}
}
Controller will call SedanCar .


###  @Qualifier

Using Qualifer we can specify the perticular service ( Car ) in Controller and spring will create the bean of that service.
So using Qualifier spring can call specific bean from multiple bean.

CarController.java
package com.vrushant.AutowiredInSpringBoot.controller;
@RestController
@RequestMapping("/cars")
public class CarController {
@Qualifier("suvCar")
@Autowired
private Car car;
@GetMapping
public String drive(){
return car.drive();
}
}
Note : All other codes will same as above code in ByType.


### Contructor

CarController.java
@RestController
@RequestMapping("/cars")
public class CarController {
private final Car car;
@Autowired
public CarController(@Qualifier("suvCar") Car car) {
this.car = car;
}
@GetMapping
public String drive(){
return car.drive();
}
}
In this , we have to specify the Qualifier in contructor and make the contructor autowired instead of variable.

Now using lombok we can automatically call the contructor by using @RequiredArgsContructor annotation. It is similar to the byName but it used when variable is declared as final.
@RestController
@RequestMapping("/cars")
@RequiredArgsConstructor
public class CarController {
private final Car sedanCar;
// @Autowired // No Need of contructor
// public CarController(@Qualifier("suvCar") Car car) {
// this.car = car;
// }
@GetMapping
public String drive(){
return sedanCar.drive();
}
}

### Setter

CarController.java
@RestController
@RequestMapping("/cars")
public class CarController {
private Car car;
@Autowired
public void setCar(@Qualifier("suvCar") Car car) {
this.car = car;
}
@GetMapping
public String drive(){
return car.drive();
}
}
In this , we are making autowired to the setter and specifing the Qualifier in setter.


### Custom Qualifier Annotation

CarController,java
@RestController
@RequestMapping("/cars")
public class CarController {
@CarQualifier("suvCar")
@Autowired
private Car car;
@GetMapping
public String drive(){
return car.drive();
}
}
To Create the custom Qualifier annotation, first create pacakage called annotation then create qualifier called CarQualifier in  it.

CarQualifier.java

Qualifier
package com.vrushant.AutowiredInSpringBoot.annotation;
import org.springframework.beans.factory.annotation.Qualifier;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Qualifier
@Target({ElementType.FIELD,ElementType.PARAMETER,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface CarQualifier {
String value();
}

### Resource 

Resource is similier as Autowired.
@RestController
@RequestMapping("/cars")
public class CarController {
@Qualifier("suvCar")
@Resource
private Car car;
@GetMapping
public String drive(){
return car.drive();
}
}

### Inject

Inject is similier as Autowired.
@RestController
@RequestMapping("/cars")
public class CarController {
@Qualifier("suvCar")
@Inject
private Car car;
@GetMapping
public String drive(){
return car.drive();
}
}

Note:  Inject required javax.inject dependency






















Comments