Dependency Injection in Springboot

background
Reading Time: 2 minutes

What is Dependency Injection?

  • It helps in injecting one object into another object
  • Make it easy to do loose coupling
  • Managing and testing the code becomes easy
  • Removes dependency from the program and provides information externally

Consider an example:

class Student {  
Marks marks;  
Student(Marks marks){  
this.marks=marks;  
}  
public void setMarks(Marks marks){  
this.marks=marks;  
}  
 } 
  • Here the instance of Marks class is provided externally
  • That could be done in two ways:
    • Using setter
    • Using constructor

Constructor Injection

  • CI via collection
  • CI via map

Setter Injection

  • SI via collection
  • SI via map

Constructor Vs Setter

Definition of Autowiring

Autowiring helps dependency injection to work faster and easier way without changing much at the code level

Ways of Autowiring

Dependency Injection without Autowiring

public class A {
    public B b;

    public void setB(B b){
	this.b = b;
    }
}
public static void main(String[] args) {
    ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
    A a = context.getBean(A.class);
    B b = context.getBean(B.class);
    a.setB(b);
    a.b; //returns b
}

Dependency Injection with Autowiring

@Component
public class A {
    @Autowired
    public B b;
}
public static void main(String[] args) {
    ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
    A a = context.getBean(A.class);
    a.b; //returns b
}
  • We don’t need a setter when we are using auto wiring, bean B gets automatically injected into bean A using @Component annotation
  • @Component annotation registers that the class as a spring bean
  • We don’t need to explicitly inject managed dependencies. Spring can automatically figure this out at runtime.

Examples

You need to use autowire attribute of the bean element to apply the autowire modes.

@Autowired with

  • Setter: Dependency is passed to the object via a method. This is useful if a different concrete object needs to be used at different times.
@Component
public class Student {
    private Marks marks;

    public Marks getmarks(){
        return this.marks;
    }

    @Autowired
    public void setMarks(Marks marks){
        this.marks = marks;
    }
}
  • Properties: If the dependency is selected and invoked at different places, we can set the dependency via a property exposed by the dependent object, which can then invoke it later
@Component
public class Student {
    @Autowired
    private Marks marks;

    public Marks getB(){
        return this.b;
    }
}
  • Constructor: Dependency is passed to the object via its constructor that accepts an interface as an argument. A concrete class object is bound to the interface handle. This is typically used if the dependent object has to use the same concrete class for its lifetime
@Component
public class Student {
    private Marks marks;

    @Autowired
    public Student(Marks marks){
        this.marks = marks;
    }

    public Marks getMarks(){
        return this.marks;
    }
}

Conclusion

Autowiring makes DI even easier. Using the @Autowired annotation on setters, properties, and constructors can save you some boilerplate code when injecting Spring-managed dependencies.
For reference please consider: Spring Autowiring – It’s a kind of magic – Part 1 , Dependency Injection