Skip to main content

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

AnnotationTypical usage
@ComponentGeneric component
@ServiceBusiness logic
@RepositoryDatabase/persistence
@ControllerMVC controller
@RestControllerREST 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: When proxyBeanMethods = true (default in @Configuration), Spring creates a CGLIB subclass proxy of your configuration class. If method A() calls method B() internally, CGLIB intercepts the invocation and ensures the singleton bean returned from B() is not instantiated twice! Setting proxyBeanMethods = 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.