Skip to content

Lab 2: Autowired

Goals

  • Understand how Spring does Dependency Injection via its Autowiring mechanism
  • Look inside Spring's ApplicationContext to better understand how it works

a. Autowire Dependencies

Inside the CoffeeOrderController class, add the following import:

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

and replace the constructor with the following:

@Autowired
public CoffeeOrderController(CoffeeOrderService coffeeOrderService) {
  System.out.println();
  System.out.println(this.getClass().getName() + " has been instantiated.");
  System.out.println("  --> Was passed a reference to a dependency: " + coffeeOrderService);
  System.out.println();
}

Now stop and re-run the CoffeeKioskApplication and notice the difference.

b. Dependencies on Dependencies

Open up the CoffeeOrderService and add the following import:

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

and replace the constructor with:

@Autowired
public CoffeeOrderService(CoffeeOrderComponent coffeeOrderComponent, CoffeeOrderSecondComponent coffeeOrderSecondComponent) {
  System.out.println();
  System.out.println(this.getClass().getName() + " has been instantiated. ");
  System.out.println("  --> Was passed a reference to two dependencies: " + coffeeOrderComponent);
  System.out.println("  -->                                        and: " + coffeeOrderSecondComponent);
  System.out.println();
}

Stop and re-run the CoffeeKioskApplication and notice the difference in terms of when the classes are instantiated. Also note that this class is autowired with multiple dependencies.

c. Dependencies As Singletons

Open up the CoffeeOrderRestController, add the import and replace the constructor as follows:

import org.springframework.beans.factory.annotation.Autowired;
@Autowired
public CoffeeOrderRestController(CoffeeOrderService coffeeOrderService) {
  System.out.println();
  System.out.println(this.getClass().getName() + " has been instantiated.");
  System.out.println("  --> Was passed a reference to a dependency: " + coffeeOrderService);
  System.out.println();
}

Stop and re-run the application and notice how the two Controller classes share the same instance of the CoffeeOrderService class.

d. Explore

Try these experiments out:

  • What happens if you try to inject (autowire) a dependency that's not annotated with a Spring annotation? Create a new Java class, without any annotations, and try to autowire it to one of the existing @Component annotated classes.

  • What happens if you create a circular dependency? Try modifying the constructor of CoffeeOrderComponent to autowire CoffeeOrderController as a dependency.


Dependency Injection

Martin Fowler's tutorial on Inversion of Control containers and Dependency Injection: https://martinfowler.com/articles/injection.html