2.1 Bean Stereotypes & Component Scan
← Back to Chapter 2: Spring Beans & Dependency Injection
In Spring, a Bean is an object that is instantiated, assembled, and otherwise managed by the Spring IoC container. Stereotype annotations provide semantic clarity and allow automated classpath discovery.
What is a Spring Bean?
A Spring Bean is an object that is created and managed by the Spring Container.
Normally in Java, we create an object like this:
PaymentService paymentService = new PaymentService();
Here, we are responsible for creating the object.
In Spring:
@Service
public class PaymentService {
}
Spring sees @Service and creates an object of PaymentService.
Conceptually:
@Service
↓
Spring detects the class
↓
Spring creates object
↓
Object becomes a Spring Bean
↓
Spring manages that Bean
So:
Bean = Java object managed by Spring.
@Component vs @bean
@Component
Put it on the class:
@Component
public class EmailService {
}
Spring discovers it through component scanning.
@Bean
Put it on a method:
@Configuration
public class AppConfig {
@Bean
public EmailService emailService() {
return new EmailService();
}
}
We manually define how the object should be created.
Stereotype Annotations Hierarchy
All stereotype annotations inherit meta-annotatively from @Component:
┌──────────────────┐
│ @Component │ (General-purpose managed bean)
└────────┬─────────┘
┌───────────────────┼───────────────────┐
│ │ │
┌────────▼─────────┐┌────────▼─────────┐┌────────▼─────────┐
│ @Service ││ @Repository ││ @Controller │
│ (Domain/Business││(Data Access Layer││(Web/Presentation │
│ Logic) ││ & Exception ││ Layer) │
│ ││ Translation) ││ │
└──────────────────┘└──────────────────┘└────────┬─────────┘
│
┌────────▼─────────┐
│ @RestController │
│(@Controller + │
│ @ResponseBody) │
└──────────────────┘
@Component
Base stereotype for any generic Spring-managed utility, helper, or worker component.
@Component
public class EmailService {
public void sendEmail() {
System.out.println("Email sent");
}
}
@Service
Encapsulates business capabilities, transaction orchestration, and application workflow logic.
@Service
public class VerificationService {
public void verifyCustomer() {
// Business logic
}
}
It tells developers:
This class contains business logic and should be managed by Spring.
Technically, @Service is a specialized form of @Component.
@Repository
Designates DAOs. Crucial benefit: Spring wraps @Repository classes with automatic persistence exception translation (converting low-level SQL/Hibernate exceptions into Spring's unchecked DataAccessException hierarchy).
@Repository
public class CustomerRepository {
public void saveCustomer() {
// Database operation
}
}
It tells Spring:
This class is responsible for database-related operations.
@Controller
Handles standard web requests (typically returns MVC view templates).
@Controller
public class CustomerController {
}
@RestController
Specialization for RESTful web services that serializes method return values directly into HTTP response bodies via Jackson.
@RestController
public class CustomerController {
@GetMapping("/customer")
public String getCustomer() {
return "Customer details";
}
}
Difference between Component, Service and Repository
| Annotation | Typical usage |
|---|---|
| @Component | Generic component |
| @Service | Business logic |
| @Repository | Database/persistence |
| @Controller | MVC controller |
| @RestController | REST API controller |
@Configuration and @Bean Mechanics
When configuring third-party libraries (where you cannot attach @Component to external source code), use Java configuration classes:
@Configuration(proxyBeanMethods = true)
public class HttpClientConfig {
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder
.setConnectTimeout(Duration.ofSeconds(3))
.setReadTimeout(Duration.ofSeconds(5))
.build();
}
}
Deep-Dive:
proxyBeanMethods: WhenproxyBeanMethods = true(default in@Configuration), Spring creates a CGLIB subclass proxy of your configuration class. If methodA()calls methodB()internally, CGLIB intercepts the invocation and ensures the singleton bean returned fromB()is not instantiated twice! SettingproxyBeanMethods = false(Lite mode) speeds up startup when inter-bean dependencies do not exist.
Component Scanning Mechanics
@ComponentScan instructs Spring where to look for annotated classes during bootstrap:
@Configuration
@ComponentScan(
basePackages = "com.codewithsarvy.crm",
excludeFilters = @ComponentScan.Filter(
type = FilterType.REGEX,
pattern = ".*TestConfig.*"
)
)
public class AppConfig {}
By default, @SpringBootApplication activates @ComponentScan over the package containing the main class and all nested child packages.