This project demonstrates how to manually configure beans in Spring
using a configuration class with @Configuration and @Bean annotations,
instead of using @Component and component scanning.
By the end of this project, you will understand how to:
- Define beans manually using a configuration class.
- Use
@Beanmethods to control the creation and naming of beans. - Inject beans into other Spring-managed components using constructor injection.
- Use
@Qualifierto specify which bean should be injected when multiple implementations exist.
src/main/java/com/example/springcustomconfig/
│
├── config/
│ └── SportConfig.java # Defines beans using @Bean methods
│
├── controller/
│ └── DemoController.java # REST controller that injects the Coach bean
│
├── model/
│ ├── Coach.java # Interface for different types of coaches
│ └── SwimCoach.java # Implementation class (not annotated with @Component)
│
└── SpringCustomConfigApplication.java # Main Spring Boot application
Instead of annotating SwimCoach with @Component, we define it in a configuration class:
@Configuration
public class SportConfig {
@Bean
public Coach swimCoach() {
return new SwimCoach();
}
}✅ This tells Spring:
“When the application starts, create and manage a bean named
swimCoachof typeSwimCoach.”
We use constructor injection to inject our custom bean into the controller:
@RestController
@RequestMapping("/")
public class DemoController {
private Coach coach;
@Autowired
public DemoController(@Qualifier("swimCoach") Coach coach) {
this.coach = coach;
}
@GetMapping("/dailyworkout")
public String getDailyWorkout() {
return coach.getDailyWorkout();
}
}The @Qualifier("swimCoach") ensures that the correct bean (the one defined in SportConfig) is injected.
public class SwimCoach implements Coach {
public SwimCoach() {
System.out.println("In constructor: " + getClass().getSimpleName());
}
@Override
public String getDailyWorkout() {
return "Swim 1000 meters as a warm up";
}
}Notice that:
- The class is not annotated with
@Component. - It becomes a Spring bean only because it’s registered via
SportConfig.
-
Run the Spring Boot app:
./mvnw spring-boot:run
-
Open your browser or use curl:
http://localhost:8080/dailyworkout -
Expected Output:
Swim 1000 meters as a warm up
In the console, you should also see:
In constructor: SwimCoach
Manual configuration gives you:
- Fine-grained control over bean creation (e.g., calling constructors with arguments).
- Flexibility to integrate external libraries or legacy classes that you can’t annotate.
- The ability to customize bean names and behaviors.
In larger applications, combining @Component scanning and manual configuration is a common and powerful approach.
@Componentvs@Bean@Configuration@Autowired@Qualifier- Dependency Injection in Spring
To continue learning:
- Try adding another
Coachimplementation (e.g.,TennisCoach). - Define both beans in
SportConfig. - Use
@Qualifierto switch between them in the controller.
Author: JAndresQS
Topic: Spring Boot Fundamentals
Concept: Manual Bean Configuration with @Bean
Tools: Java 21+, Spring Boot 3.5.6, Maven