Week 1 Day 3 — Beans and Bean Definitions
Goal
Today I want to understand what a Spring bean really is.
Main questions:
- What is a Spring bean?
- What is a
BeanDefinition? - How does Spring register beans?
- What is the difference between
@Componentand@Bean? - What is the difference between
@Component,@Service,@Repository, and@Controller? - When should I use each annotation?
- What are common exam traps about beans?
1. Quick Review from Day 2
In Day 2, I learned:
ApplicationContextis the main Spring container.ApplicationContextmanages Spring beans.BeanFactoryis the basic container.ApplicationContextextendsBeanFactory.BeanDefinitionis the recipe.- Bean is the actual object.
Memory sentence:
BeanDefinition is the recipe. Bean is the object.
Today I go deeper into beans.
2. What Is a Spring Bean?
A Spring bean is an object managed by the Spring IoC container.
Simple definition:
A Spring bean is an object created, configured, wired, and managed by Spring.
Example:
@Service
public class OrderService {
}
If Spring discovers this class and creates an object from it, that object is a Spring bean.
3. Normal Java Object vs Spring Bean
Normal Java Object
OrderService orderService = new OrderService();
This object is created manually.
Spring does not manage it.
Spring cannot automatically:
- inject dependencies
- call lifecycle callbacks
- apply
@Transactional - apply security proxies
- manage destruction
Spring Bean
@Service
public class OrderService {
}
Spring creates and manages this object.
Spring can:
- inject dependencies
- manage lifecycle
- apply AOP proxies
- apply transactions
- apply security
- reuse the same singleton instance
4. Exam Definition
For the exam, use this answer:
A Spring bean is an object whose lifecycle is managed by the Spring IoC container. Spring creates the object, injects its dependencies, configures it, and can apply additional behavior such as lifecycle callbacks, AOP proxies, transactions, and security.
5. What Does Spring Manage Exactly?
When Spring manages a bean, it can manage:
1. Object creation
2. Dependency injection
3. Configuration
4. Bean name
5. Bean scope
6. Initialization
7. Destruction
8. AOP proxy wrapping
9. Transaction behavior
10. Security method interception
Example:
@Service
public class PaymentService {
@Transactional
public void pay() {
// business logic
}
}
Spring does not only create PaymentService.
Spring may also wrap it with a proxy so @Transactional works.
6. What Is a BeanDefinition?
Before Spring creates a bean, it stores metadata about that bean.
This metadata is called a BeanDefinition.
Simple definition:
A
BeanDefinitionis metadata that tells Spring how to create and manage a bean.
A BeanDefinition may contain:
- bean class
- bean name
- scope
- constructor arguments
- dependencies
- lazy/eager setting
- init method
- destroy method
- factory method
- whether the bean is primary
- qualifiers
7. BeanDefinition vs Bean
| Concept | Meaning |
|---|---|
BeanDefinition | Metadata / recipe |
| Bean | Actual object |
Example:
BeanDefinition:
- class: OrderService
- scope: singleton
- dependency: OrderRepository
Bean:
- actual OrderService object in memory
Memory sentence:
BeanDefinitionis the recipe. Bean is the cooked meal.
8. How Does Spring Register Beans?
Spring can register beans in different ways.
The two most important ways are:
- Component scanning
@Beanmethods inside configuration classes
9. Way 1 — Component Scanning
Spring scans packages and looks for annotations like:
@Component
@Service
@Repository
@Controller
@RestController
Example:
@Service
public class OrderService {
}
Spring sees @Service, creates a BeanDefinition, and later creates the bean.
10. What Is Component Scanning?
Component scanning means:
Spring scans selected packages to find classes annotated with Spring stereotype annotations.
Example:
@SpringBootApplication
public class MyApplication {
}
@SpringBootApplication includes:
@ComponentScan
By default, Spring scans the package of the main application class and its subpackages.
11. Important Package Structure Example
Good structure:
com.example.app
├── MyApplication.java
├── controller
│ └── OrderController.java
├── service
│ └── OrderService.java
└── repository
└── OrderRepository.java
If MyApplication is in:
com.example.app
Spring scans:
com.example.app.controller
com.example.app.service
com.example.app.repository
This works well.
12. Bad Package Structure Example
Bad structure:
com.example.app
└── MyApplication.java
com.other.service
└── OrderService.java
If the main class is in com.example.app, Spring does not automatically scan com.other.service.
So OrderService may not become a bean.
Exam trap:
A class annotated with
@Serviceis not registered as a bean if it is outside component scanning.
13. Way 2 — @Bean Method
The second common way to register beans is using @Bean.
Example:
@Configuration
public class AppConfig {
@Bean
public Clock clock() {
return Clock.systemUTC();
}
}
Here, the return value of the method becomes a Spring bean.
Spring registers a bean named:
clock
The bean type is:
Clock
14. When Should I Use @Bean?
Use @Bean when:
- the class comes from a third-party library
- I cannot modify the class
- I need custom creation logic
- I want to configure an object manually
- I need to choose constructor values myself
Example:
@Configuration
public class AppConfig {
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.findAndRegisterModules();
return mapper;
}
}
ObjectMapper is from Jackson, not from my own application.
So @Bean is a good choice.
15. @Component vs @Bean
This is very important.
| Topic | @Component | @Bean |
|---|---|---|
| Where used? | On class | On method |
| Who creates object? | Spring directly creates class | Method returns object |
| Best for | My own classes | Third-party or custom setup |
| Needs component scanning? | Yes | Configuration class must be registered |
| Example | OrderService | Clock, ObjectMapper, RestTemplate |
16. Example: Use @Component
Use @Component or @Service for your own application classes.
@Service
public class OrderService {
public void createOrder() {
System.out.println("Order created");
}
}
This is simple and clean.
17. Example: Use @Bean
Use @Bean when you cannot annotate the class.
@Configuration
public class TimeConfig {
@Bean
public Clock clock() {
return Clock.systemUTC();
}
}
I cannot add @Component to Clock, because Clock is a Java library class.
So I create it with @Bean.
18. Stereotype Annotations
Spring has several common stereotype annotations.
@Component
@Service
@Repository
@Controller
@RestController
They all can register Spring beans.
But they communicate different roles.
19. @Component
@Component is the generic annotation.
Use it for a general Spring-managed class.
Example:
@Component
public class SlugGenerator {
}
Meaning:
This is a Spring-managed component.
20. @Service
@Service is used for service-layer classes.
Example:
@Service
public class OrderService {
}
Meaning:
This class contains business logic.
Service layer usually coordinates:
- validation
- business rules
- repositories
- transactions
- domain logic
21. @Repository
@Repository is used for persistence-layer classes.
Example:
@Repository
public class JdbcOrderRepository {
}
Meaning:
This class talks to the database or persistence system.
Important exam point:
@Repositorycan enable persistence exception translation.
That means database-specific exceptions can be translated into Spring’s DataAccessException hierarchy.
22. @Controller
@Controller is used for Spring MVC controllers that usually return views.
Example:
@Controller
public class HomeController {
@GetMapping("/")
public String home() {
return "home";
}
}
This is common in traditional server-rendered MVC applications.
23. @RestController
@RestController is used for REST APIs.
Example:
@RestController
@RequestMapping("/api/orders")
public class OrderController {
@GetMapping("/{id}")
public OrderResponse getOrder(@PathVariable Long id) {
return new OrderResponse(id, "Book");
}
}
Important:
@RestController
is a combination of:
@Controller
@ResponseBody
This means return values are written directly to the HTTP response body, usually as JSON.
24. Comparison Table
| Annotation | Layer | Main meaning |
|---|---|---|
@Component | generic | general Spring bean |
@Service | service | business logic |
@Repository | persistence | database access + exception translation |
@Controller | web MVC | controller returning views |
@RestController | REST API | controller returning response body / JSON |
@Configuration | config | class defining bean methods |
@Bean | config method | return value becomes bean |
25. Are @Service and @Repository Technically Different?
Technically, both are specializations of @Component.
So both can register beans.
But they are not only for decoration.
Important difference:
@Serviceshows business logic role.@Repositoryshows persistence role and can support exception translation.
Exam memory sentence:
@Serviceand@Repositoryare both component stereotypes, but@Repositoryhas special persistence exception translation behavior.
26. Default Bean Name
By default, Spring creates the bean name from the class name with lowercase first letter.
Example:
@Service
public class OrderService {
}
Default bean name:
orderService
Another example:
@Component
public class EmailSender {
}
Default bean name:
emailSender
27. Custom Bean Name
You can specify a custom name.
@Service("mainOrderService")
public class OrderService {
}
Bean name:
mainOrderService
With @Bean:
@Bean("utcClock")
public Clock clock() {
return Clock.systemUTC();
}
Bean name:
utcClock
28. Real Question: Can One Class Have Multiple Beans?
Yes, but not directly with one @Component class.
With @Bean, I can create multiple beans of the same type.
Example:
@Configuration
public class ClockConfig {
@Bean
public Clock utcClock() {
return Clock.systemUTC();
}
@Bean
public Clock systemClock() {
return Clock.systemDefaultZone();
}
}
Now Spring has two Clock beans:
utcClock
systemClock
If another bean needs Clock, Spring may not know which one to inject.
This causes ambiguity.
Later we solve it with:
@Primary
@Qualifier
29. Real Question: What Happens If Two Beans Have the Same Type?
Example:
@Bean
public Clock utcClock() {
return Clock.systemUTC();
}
@Bean
public Clock berlinClock() {
return Clock.system(ZoneId.of("Europe/Berlin"));
}
And another class needs:
public TimeService(Clock clock) {
this.clock = clock;
}
Problem:
Spring finds two Clock beans.
Spring does not know which one to inject.
Application fails to start.
Possible solutions:
- mark one bean as
@Primary - use
@Qualifier - inject by specific bean name
- inject
List<Clock>if I want all beans
30. @Primary
@Primary tells Spring:
Use this bean by default when multiple candidates exist.
Example:
@Bean
@Primary
public Clock utcClock() {
return Clock.systemUTC();
}
@Bean
public Clock berlinClock() {
return Clock.system(ZoneId.of("Europe/Berlin"));
}
Now this works:
public TimeService(Clock clock) {
this.clock = clock;
}
Spring injects utcClock.
31. @Qualifier
@Qualifier tells Spring exactly which bean to inject.
Example:
public TimeService(@Qualifier("berlinClock") Clock clock) {
this.clock = clock;
}
Now Spring injects:
berlinClock
Even if another bean is marked @Primary, @Qualifier is more specific.
Memory sentence:
@Primaryis the default choice.@Qualifieris the exact choice.
32. Real Question: Can I Inject All Beans of One Type?
Yes.
Example:
@Component
public class NotificationService {
private final List<NotificationSender> senders;
public NotificationService(List<NotificationSender> senders) {
this.senders = senders;
}
}
If I have:
@Component
public class EmailSender implements NotificationSender {
}
@Component
public class SmsSender implements NotificationSender {
}
Spring injects both into the list.
This is useful for strategy patterns.
33. Real Question: Can I Make a Bean Optional?
Yes.
Options include:
Optional<MyService>
ObjectProvider<MyService>
@Nullable
Example:
@Component
public class ReportService {
public ReportService(Optional<AuditService> auditService) {
}
}
Better for advanced control:
@Component
public class ReportService {
private final ObjectProvider<AuditService> auditServiceProvider;
public ReportService(ObjectProvider<AuditService> auditServiceProvider) {
this.auditServiceProvider = auditServiceProvider;
}
}
This is useful when the dependency may or may not exist.
34. Real Question: Can I Get a Bean Manually?
Yes, but it is usually not recommended in normal business code.
Example:
ApplicationContext context = SpringApplication.run(App.class, args);
OrderService orderService = context.getBean(OrderService.class);
This works, but normally I should prefer constructor injection.
Why?
Because constructor injection makes dependencies clear.
Bad style in normal service code:
@Component
public class OrderService {
private final ApplicationContext context;
public OrderService(ApplicationContext context) {
this.context = context;
}
public void process() {
PaymentService paymentService = context.getBean(PaymentService.class);
}
}
This hides dependencies.
Better:
@Component
public class OrderService {
private final PaymentService paymentService;
public OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
}
35. Real Question: Is Every Bean a Singleton?
No.
The default scope is singleton, but Spring supports different scopes.
Common scopes:
singleton
prototype
request
session
application
websocket
Today I only remember:
Default scope is singleton.
We will study scopes more deeply later.
36. Real Question: Does Singleton Mean Java Singleton Pattern?
No.
Spring singleton means:
one bean instance per Spring container.
Java Singleton pattern usually means:
one instance per JVM, controlled by static access.
They are not the same.
Exam trap:
Spring singleton is not the same as the classic Java Singleton pattern.
37. Real Question: What Happens If Bean Creation Fails?
If Spring cannot create a required bean, the application usually fails to start.
Example:
@Service
public class OrderService {
public OrderService(OrderRepository orderRepository) {
}
}
But no OrderRepository bean exists.
Then Spring throws an error like:
No qualifying bean of type 'OrderRepository' available
This is useful because errors are detected early.
38. Real Question: What If I Add @Service but Spring Still Cannot Find It?
Possible reasons:
- The class is outside the scanned package.
- The class is not public or cannot be created.
- The class has constructor dependencies that are missing.
- The annotation is imported from the wrong package.
- The profile condition does not match.
- The bean is conditional and condition is false.
Most common for beginners:
The class is outside component scanning.
39. Real Question: Can Interfaces Be Beans?
Usually, an interface alone is not a bean because Spring cannot instantiate an interface.
Example:
public interface OrderRepository {
}
This is not enough.
Spring needs an implementation:
@Repository
public class JpaOrderRepository implements OrderRepository {
}
But Spring Data JPA is special:
public interface OrderRepository extends JpaRepository<Order, Long> {
}
Spring Data creates a proxy implementation automatically.
So the repository interface can become a bean through Spring Data infrastructure.
40. Real Question: Can Abstract Classes Be Beans?
Usually no, because Spring cannot instantiate an abstract class directly.
Example:
@Component
public abstract class BaseService {
}
This cannot be created as a normal bean because it is abstract.
But concrete subclasses can be beans.
41. Real Question: What Is a Bean Candidate?
A bean candidate is a bean that Spring can use to satisfy a dependency.
Example:
public OrderService(PaymentService paymentService) {
}
Spring searches for beans of type:
PaymentService
All matching beans are candidates.
If exactly one candidate exists, Spring injects it.
If multiple candidates exist, Spring needs more information.
42. Real Question: What Is Autowiring?
Autowiring means Spring automatically resolves and injects dependencies.
Example:
@Service
public class OrderService {
private final OrderRepository orderRepository;
public OrderService(OrderRepository orderRepository) {
this.orderRepository = orderRepository;
}
}
Spring sees the constructor parameter and automatically injects an OrderRepository bean.
In modern Spring, if a class has only one constructor, @Autowired is optional.
43. Constructor Injection with @Autowired
Old or explicit style:
@Service
public class OrderService {
private final OrderRepository orderRepository;
@Autowired
public OrderService(OrderRepository orderRepository) {
this.orderRepository = orderRepository;
}
}
Modern style:
@Service
public class OrderService {
private final OrderRepository orderRepository;
public OrderService(OrderRepository orderRepository) {
this.orderRepository = orderRepository;
}
}
Both work if there is only one constructor.
Exam trap:
@Autowiredon a single constructor is optional in modern Spring.
44. Field Injection
Field injection:
@Service
public class OrderService {
@Autowired
private OrderRepository orderRepository;
}
This works, but it is discouraged.
Why?
- dependencies are hidden
- harder to test
- cannot make fields final
- object can be created in invalid state
- encourages poor design
Best practice:
Prefer constructor injection.
45. Setter Injection
Setter injection:
@Service
public class OrderService {
private OrderRepository orderRepository;
@Autowired
public void setOrderRepository(OrderRepository orderRepository) {
this.orderRepository = orderRepository;
}
}
Use setter injection mostly for optional dependencies.
For required dependencies, prefer constructor injection.
46. Constructor vs Setter vs Field Injection
| Type | Best for | Recommendation |
|---|---|---|
| Constructor injection | required dependencies | best |
| Setter injection | optional dependencies | acceptable |
| Field injection | quick demos/tests | avoid in production |
Memory sentence:
Required dependencies should be constructor-injected.
47. Tiny Code Proof
Create this small example:
public interface NotificationSender {
void send(String message);
}
@Component
public class EmailNotificationSender implements NotificationSender {
@Override
public void send(String message) {
System.out.println("Email: " + message);
}
}
@Service
public class OrderService {
private final NotificationSender notificationSender;
public OrderService(NotificationSender notificationSender) {
this.notificationSender = notificationSender;
}
public void createOrder() {
notificationSender.send("Order created");
}
}
Question:
Why can Spring inject
EmailNotificationSenderintoNotificationSender?
Answer:
Because EmailNotificationSender is a Spring bean and it implements NotificationSender. Spring can inject a bean by interface type when there is exactly one matching implementation.
48. Tiny Code Proof with Ambiguity
Now add:
@Component
public class SmsNotificationSender implements NotificationSender {
@Override
public void send(String message) {
System.out.println("SMS: " + message);
}
}
Now Spring has two beans of type NotificationSender.
emailNotificationSender
smsNotificationSender
This constructor becomes ambiguous:
public OrderService(NotificationSender notificationSender) {
}
Spring does not know which one to inject.
Possible fix:
public OrderService(
@Qualifier("emailNotificationSender") NotificationSender notificationSender
) {
this.notificationSender = notificationSender;
}
49. Exam Traps
Trap 1
@Service, @Repository, and @Controller are specializations of @Component.
Trap 2
@Repository can provide exception translation.
Trap 3
@RestController equals @Controller plus @ResponseBody.
Trap 4
A class annotated with @Service is not a bean if it is outside component scanning.
Trap 5
A manually created object with new is not automatically managed by Spring.
Trap 6
BeanDefinition is metadata. Bean is the actual object.
Trap 7
@Bean is useful for third-party classes or custom construction logic.
Trap 8
If multiple beans of the same type exist, Spring needs @Primary, @Qualifier, or another way to resolve ambiguity.
Trap 9
@Autowired on a single constructor is optional in modern Spring.
Trap 10
Spring singleton means one instance per Spring container, not classic Java Singleton pattern.
50. Interview Answer
Question:
What is a Spring bean?
Good answer:
A Spring bean is an object managed by the Spring IoC container. Spring creates the bean, injects its dependencies, configures it, and manages its lifecycle. Beans can be registered through component scanning using annotations like @Component, @Service, and @Repository, or manually through @Bean methods in configuration classes. Because the object is managed by Spring, Spring can also apply additional behavior such as AOP proxies, transactions, and security. A normal object created with new is not automatically a Spring bean.
51. Interview Answer
Question:
What is the difference between
@Componentand@Bean?
Good answer:
@Component is used on a class, and Spring discovers it through component scanning. It is usually used for my own application classes, such as services, helpers, or components. @Bean is used on a method inside a configuration class, and the return value of that method becomes a Spring bean. @Bean is useful when I need to create a third-party object, configure construction manually, or cannot annotate the class directly.
52. Interview Answer
Question:
What is the difference between
@Serviceand@Repository?
Good answer:
Both @Service and @Repository are stereotype annotations and both are specializations of @Component, so both can register Spring beans. The difference is semantic and technical. @Service marks a class as part of the business logic layer. @Repository marks a class as part of the persistence layer and can support persistence exception translation into Spring’s DataAccessException hierarchy.
53. Interview Answer
Question:
Why is constructor injection recommended?
Good answer:
Constructor injection is recommended because it makes required dependencies explicit. It allows fields to be final, supports immutability, and makes the class easier to test. It also prevents the object from being created without its required dependencies. Field injection hides dependencies and makes testing harder, so constructor injection is preferred in production code.
Practice Questions and Answers
Question 1
What is a Spring bean?
Answer:
A Spring bean is an object created and managed by the Spring IoC container. Spring can create it, inject dependencies into it, configure it, manage its lifecycle, and apply additional behavior such as AOP proxies, transactions, or security.
Question 2
What is a BeanDefinition?
Answer:
A BeanDefinition is metadata that tells Spring how to create and manage a bean. It can contain information such as the bean class, bean name, scope, dependencies, constructor arguments, init method, destroy method, and lazy/eager behavior.
Question 3
What is the difference between a BeanDefinition and a bean?
Answer:
A BeanDefinition is the recipe or metadata. A bean is the actual object created from that metadata and managed by Spring.
Question 4
What is the difference between @Component and @Bean?
Answer:
@Component is used on a class and is discovered through component scanning. @Bean is used on a method inside a configuration class, and the method return value becomes a Spring bean.
Question 5
When should I use @Bean instead of @Component?
Answer:
Use @Bean when the class comes from a third-party library, when I cannot modify the class, or when object creation needs custom configuration logic.
Question 6
What is the difference between @Component, @Service, and @Repository?
Answer:
@Component is a generic Spring-managed component. @Service is used for service-layer classes containing business logic. @Repository is used for persistence-layer classes that access data.
Question 7
What is special about @Repository?
Answer:
@Repository can support persistence exception translation. It can translate database-specific exceptions into Spring’s DataAccessException hierarchy.
Question 8
What does @RestController include?
Answer:
@RestController includes @Controller and @ResponseBody. It is used for REST APIs where return values are written directly to the HTTP response body, usually as JSON.
Question 9
Is this object a Spring bean?
OrderService service = new OrderService();
Answer:
No. This object is created manually with new, so Spring does not automatically manage it.
Question 10
Is this class automatically a bean?
@Service
public class OrderService {
}
Answer:
It can become a Spring bean if it is inside a package scanned by Spring component scanning.
Question 11
What can prevent this @Service class from becoming a bean?
@Service
public class OrderService {
}
Answer:
Possible reasons include: the class is outside the scanned package, a required dependency is missing, the active profile does not match, a condition is false, or the class cannot be instantiated.
Question 12
What happens if Spring finds two beans of the same type and does not know which one to inject?
Answer:
Spring fails to start with an ambiguity error, usually saying that multiple beans match the required type. I need to resolve it with @Primary, @Qualifier, a more specific type, or by injecting a collection.
Question 13
What is the difference between @Primary and @Qualifier?
Answer:
@Primary marks one bean as the default choice when multiple candidates exist. @Qualifier selects a specific bean explicitly. @Qualifier is more precise.
Question 14
Why is constructor injection better than field injection?
Answer:
Constructor injection makes dependencies explicit, allows final fields, supports immutability, improves testability, and prevents creating the object without required dependencies.
Question 15
Is @Autowired required on a single constructor?
Answer:
No. In modern Spring, if a class has only one constructor, @Autowired is optional.
Question 16
Can an interface be a Spring bean?
Answer:
Usually an interface alone is not a bean because Spring cannot instantiate an interface. But frameworks like Spring Data JPA can create proxy implementations for repository interfaces, so those interfaces can become beans through Spring infrastructure.
Question 17
Can Spring inject a class by its interface type?
Answer:
Yes. Spring can inject a bean by interface type if there is exactly one matching implementation or if ambiguity is resolved with @Primary or @Qualifier.
Question 18
What is the default bean name for this class?
@Service
public class PaymentService {
}
Answer:
The default bean name is:
paymentService
Spring usually uses the class name with the first letter lowercase.
Question 19
What is the default bean scope?
Answer:
The default bean scope is:
singleton
Question 20
Does Spring singleton mean the same thing as Java Singleton pattern?
Answer:
No. Spring singleton means one bean instance per Spring container. Java Singleton pattern usually means one instance per JVM controlled by static access.
Final Memory Sentences
- A Spring bean is an object managed by Spring.
BeanDefinitionis the recipe. Bean is the object.@Componentis used on classes.@Beanis used on methods.- Use
@Beanfor third-party objects or custom creation logic. @Servicemarks business logic.@Repositorymarks persistence logic and can enable exception translation.@RestControllerequals@Controllerplus@ResponseBody.- A class must be inside component scanning to become a bean.
- Objects created with
neware not automatically Spring-managed. - Constructor injection is preferred.
@Autowiredon a single constructor is optional.@Primarygives a default bean.@Qualifierselects an exact bean.- Default bean scope is singleton.
- Spring singleton is not the same as Java Singleton pattern.