Techniques to Master Bean Visibility in Spring: Comparing @ComponentScan, @Import, and @Configuration
In any well-structured Spring application, managing bean visibility is like managing the backstage of a theater—too much exposure and you lose control; too little and your actors (beans) can’t perform. Developers often rely on annotations like @C...

I am Tuanh.net. As of 2024, I have accumulated 8 years of experience in backend programming. I am delighted to connect and share my knowledge with everyone.
1. Understanding the Fundamentals
1.1 The Role of Bean Visibility
core-module/
├─ services/
├─ configs/
web-module/
├─ controllers/
├─ dto/
2. @ComponentScan – Discovering Beans Automatically
2.1 How @ComponentScan Works
@Configuration
@ComponentScan(basePackages = "com.example.core.services")
public class CoreConfig {
}
“Hey, scan everything under com.example.core.services and register them as beans.”
2.2 Limitations of @ComponentScan
- It may unintentionally expose beans to other modules.
- Harder to trace which beans are loaded.
- Risk of “bean duplication” if multiple contexts overlap scans.
@Configuration
@ComponentScan("com.example")
public class AppConfig {}
3. @Import – The Explicit Connector
3.1 How @Import Works
@Configuration
@Import(CoreConfig.class)
public class WebConfig {
}
@Configuration
@Import({CoreConfig.class, SecurityConfig.class})
public class AppConfig {
}
3.2 Importing Non-Configuration Classes
public class UtilityBean {
public String getInfo() {
return "Hello from UtilityBean";
}
}
@Configuration
@Import(UtilityBean.class)
public class UtilConfig {}
No @Component required. This is incredibly useful for internal shared beans you don’t want scanned globally.
4. @Configuration – The Blueprint of Bean Creation
4.1 How @Configuration Defines Beans
@Configuration
public class ServiceConfig {
@Bean
public EmailService emailService() {
return new EmailService();
}
}
Every @Bean is a contract between your module and Spring’s container.
4.2 Full vs Lite @Configuration Modes
- Full mode (@Configuration): uses CGLIB proxies to ensure singleton behavior.
- Lite mode (class annotated with @Component containing @Bean methods): does not proxy, so beans may be re-instantiated if called directly.
@Component
public class LiteConfig {
@Bean
public Foo foo() {
return new Foo();
}
}
Therefore, always prefer @Configuration for reliable singletons and predictable dependency graphs.
5. Combining the Three Annotations
5.1 Real-World Example
@Configuration
@ComponentScan("com.example.core.services")
public class CoreConfig {
@Bean
public AuditService auditService() {
return new AuditService();
}
}
@Configuration
@Import(CoreConfig.class)
@ComponentScan("com.example.web.controllers")
public class WebConfig {
}
- @ComponentScan in WebConfig loads only controllers.
- @Import(CoreConfig.class) explicitly pulls in service beans from the core module.
- No accidental scanning beyond intended boundaries.
5.2 When to Use Which
| Annotation | Best Use Case | Pros | Cons |
| ------------------ | ----------------------------------------------- | ----------------------- | -------------------- |
| @ComponentScan | For auto-detection in monolithic or simple apps | Convenient | Risk of bean overlap |
| @Import | For modular, explicit linking between contexts | Precise control | Slightly verbose |
| @Configuration | For defining bean creation manually | Deterministic, powerful | Requires boilerplate |
6. Advanced Techniques and Insights
6.1 Combining with @Profile or @Conditional
@Configuration
@Profile("dev")
public class DevOnlyConfig {
@Bean
public MockEmailService mockEmailService() {
return new MockEmailService();
}
}
6.2 Avoiding Bean Conflicts Across Modules
- @Qualifier for disambiguation
- @Primary to set a default
- or restructure your module imports to avoid conflicts entirely.
7. Conclusion: Strategic Bean Management
- Use @ComponentScan for convenience in small projects.
- Use @Import when you want explicit, modular inclusion.
- Use @Configuration to handcraft deterministic beans.
Read more at : Techniques to Master Bean Visibility in Spring: Comparing @ComponentScan, @Import, and @Configuration





