A Beginner’s Guide to Spring Boot Dependency Injection with Qualifiers
18/05/25
5 mins
In modern Java development, Spring Boot stands out for its ability to reduce boilerplate and simplify configuration. One of its core strengths is how it manages object creation and dependency injection using interfaces and annotations.
In this blog post, we’ll look at a simple Spring Boot example that demonstrates how Spring uses dependency injection and Inversion of Control (IoC) to wire together components without manual instantiation. This setup uses one interface, three implementations, and an IoC-managed class that chooses which one to use based on annotations.
1. Overview of the Project Structure
The goal of this sample project is to simulate a course purchasing system with the following components:
-
ICourse
— an interface representing a course. -
JavaCourse
,SpringBootCourse
, andDevOpsCourse
— three different course implementations. -
College
— a service class that depends on theICourse
interface. -
SpringBoot02Application
— the main application class that bootstraps the Spring context.
2. The Interface: ICourse
This interface defines the contract for any course service.
public interface ICourse { boolean purchase(double fee); }
3. The Implementations
Each course implements the ICourse
interface and is marked with the @Component
annotation so Spring can detect and register it as a bean.
JavaCourse.java
@Component("java") public class JavaCourse implements ICourse { public boolean purchase(double fee) { System.out.println("Java Course Purchased. Fee: ₹" + fee); return true; } }
SpringBootCourse.java
@Component("spring") public class SpringBootCourse implements ICourse { public boolean purchase(double fee) { System.out.println("Spring Boot Course Purchased. Fee: ₹" + fee); return true; } }
DevOpsCourse.java
@Component("devops") public class DevOpsCourse implements ICourse { public boolean purchase(double fee) { System.out.println("DevOps Course Purchased. Fee: ₹" + fee); return true; } }
4. The Dependency Injection Logic in College.java
This is where Spring's Dependency Injection kicks in. The College
class depends on an ICourse
implementation, and the actual implementation to inject is decided using the @Qualifier
annotation.
@Component public class College { private ICourse course; @Autowired public College(@Qualifier("spring") ICourse course) { this.course = course; } public boolean buyTheCourse(double fee) { return course.purchase(fee); } }
Here, the @Qualifier("spring")
ensures that Spring injects the SpringBootCourse
bean.
5. Bootstrapping the Application: SpringBoot02Application.java
This is the main class where the Spring Boot application starts. It uses SpringApplication.run()
to launch the application and get access to the application context.
@SpringBootApplication public class SpringBoot02Application { public static void main(String[] args) { ConfigurableApplicationContext container = SpringApplication.run(SpringBoot02Application.class, args); College college = container.getBean(College.class); boolean status = college.buyTheCourse(4545.4); if (status) System.out.println("Enrolled to Course"); else System.out.println("Failed to enroll"); } }
6. Sample Output
If the @Qualifier("spring")
is used in College
, the output will be:
Spring Boot Course Purchased. Fee: ₹4545.4 Enrolled to Course
7. Key Takeaways
-
Interface-Based Design: Promotes loose coupling and high flexibility.
-
Multiple Implementations: Can be easily managed and switched using
@Qualifier
. -
Annotation-Driven Configuration: Removes the need for XML configuration files.
-
Spring Boot’s Simplicity: Automatically handles component scanning and dependency wiring, allowing developers to focus on business logic.
Conclusion
This example highlights the power of Spring Boot in managing dependencies and simplifying application architecture. By using interfaces, annotations, and Spring's IoC container, you can build clean, scalable applications that are easy to maintain and extend. Whether you're working on a microservice or a monolith, this pattern of interface-driven design with Spring Boot is a solid foundation.