Dependency Injection Basics
A simple Spring Boot project demonstrating the basics of Dependency Injection (DI) using Person and Pet (Cat and Dog) examples.
Step 1: Setup your Project
Create a new Spring Boot project using Spring Initializr with:
- Spring Web dependency
- Spring Boot Devtools dependency (allows hot reloading)
- Java version 17 or higher
- Maven project
Step 2: Initial Implementation
Create the following initial classes and interfaces:
Pet.java
public interface Pet {
void feed();
}
Cat.java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
public class Cat implements Pet {
private static final Logger logger = LoggerFactory.getLogger(Cat.class);
@Override
public void feed() {
logger.info("Feeding the cat... ");
}
}
Person.java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
public class Person {
private static final Logger logger = LoggerFactory.getLogger(Person.class);
private final Pet pet;
public Person(Pet pet) {
this.pet = pet;
}
public void feedPet() {
logger.info("Feeding the pet...");
pet.feed();
}
}
Step 3: Run Your Application
Update your main application to use CommandLineRunner:
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class LabOneDemoApplication {
public static void main(String[] args) {
SpringApplication.run(LabOneDemoApplication.class, args);
}
@Bean
public CommandLineRunner demo(Person person) {
return args -> {
person.feedPet();
};
}
}
Run your application:
./mvnw spring-boot:run
Lab Extension Task: Adding a Dog
Task Instructions:
- Add a new class Dog that implements the Pet interface.
- Annotate it correctly so Spring recognizes it.
- Rerun your application. Observe what happens.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
public class Dog implements Pet {
private static final Logger logger = LoggerFactory.getLogger(Dog.class);
@Override
public void feed() {
logger.info("Feeding the dog...");
}
}
Issue and Task: Resolving Bean Ambiguity
When you run the application after adding Dog, you will encounter an issue:
Field pet in Person required a single bean, but 2 were found: cat, dog.
Task:
- Research and apply the correct annotation (@Qualifier) to explicitly define which pet implementation (Cat or Dog) should be injected.
- Run the application again and verify that the chosen pet feeds correctly.
@Component
public class Person {
private static final Logger logger = LoggerFactory.getLogger(Person.class);
private final Pet pet;
public Person(@Qualifier("dog") Pet pet) { // Use "cat" to inject Cat instead
this.pet = pet;
}
public void feedPet() {
logger.info("Feeding the pet...");
pet.feed();
}
}
Optional Advanced Task: Dynamic Pet Selection Service
Task:
- Create a new service class (PetService) that returns either the Cat or Dog implementation based on a command-line argument.
- Update your application to dynamically inject the chosen pet at runtime based on input arguments.
@Component
public class Person {
private static final Logger logger = LoggerFactory.getLogger(Person.class);
private final Pet pet;
public Person(Pet pet) { // Remove the qualifier for Pet
this.pet = pet;
}
public void feedPet() {
logger.info("Feeding the pet...");
pet.feed();
}
}
@SpringBootApplication
public class LabOneDemoApplication {
public static void main(String[] args) {
SpringApplication.run(LabOneDemoApplication.class, args);
}
@Bean
public CommandLineRunner demo(ApplicationContext context) {
return args -> {
String petType = args.length > 0 ? args[0] : "dog";
Pet pet = context.getBean(petType, Pet.class);
Person person = new Person(pet);
person.feedPet();
};
}
}
Example run command:
./mvnw spring-boot:run -Dspring-boot.run.arguments=dog
Verify the output dynamically changes depending on the provided argument.