What is a Bean in Spring?
4. BeanDefinition can be modified via BeanFactoryPostProcessor 5. Scanning is slow on large projects -> limit packages
Junior Level
Bean is an object managed by the Spring Container (ApplicationContext).
“Managed” means: Spring creates the object itself, injects its dependencies, can wrap it in a proxy to add behavior (transactions, security, caching), and calls initialization/cleanup methods. You do not do new Bean() - Spring does.
Simple analogy: Spring is a hotel. A bean is a guest who is registered and receives all services from the hotel.
Regular object:
User user = new User(); // You create it yourself
Bean:
@Service // Spring will create and manage it itself
public class UserService { }
Difference:
| Regular object | Spring Bean |
|---|---|
You create via new |
Spring creates itself |
| You manage the lifecycle | Spring manages the lifecycle |
| No dependencies | Dependencies injected automatically |
| No proxy | Can be wrapped in Proxy |
Middle Level
BeanDefinition
BeanDefinition = "recipe" for creating a bean
-> Class name
-> Scope (Singleton, Prototype)
-> Dependencies
-> Init/Destroy methods
-> Spring first creates BeanDefinition
-> Then creates a bean from it
How to Create a Bean
1. Stereotype annotations:
@Component // Base
@Service // Business logic
@Repository // Database access
@Controller // Web controller
2. Java Config:
@Configuration
public class Config {
@Bean
public ObjectMapper mapper() {
return new ObjectMapper();
}
}
Proxying
@Transactional // Spring will create a Proxy around the bean
public void save() { }
// You receive not the object, but a Proxy!
// Proxy -> intercepts call -> adds transaction -> calls method
Declaration Methods
1. @Component + @ComponentScan -> automatic scanning
2. @Bean in @Configuration -> manual configuration
3. @Import -> import configurations
Senior Level
DefaultListableBeanFactory
Heart of Spring:
-> BeanDefinitionRegistry -> stores recipes
-> Singleton Objects Cache -> stores created beans
-> ConcurrentHashMap for thread safety
-> Lazy initialization (except Singleton by default)
Proxy Types
JDK Dynamic Proxy - built-in Java mechanism for proxying ONLY by interfaces. Creates an object implementing the same interface and delegates calls to the real object.
JDK Dynamic Proxy:
-> If class implements an interface
-> Proxies only interface methods
CGLIB - library for creating subclasses at runtime. Spring uses it when a class does not implement interfaces. The subclass intercepts method calls and adds behavior.
CGLIB:
-> If no interface
-> Creates subclass at runtime
-> Cannot proxy final methods!
Bean vs POJO
POJO and Bean are NOT different types of classes. The same class can be a POJO (created via `new`) or a Bean (created by Spring). The difference is WHO created the object and who manages it.
POJO:
-> new User()
-> You manage
Bean:
-> Created via Reflection/CGLIB
-> DI of dependencies
-> Can be a Proxy
-> Lifecycle: @PostConstruct, @PreDestroy
-> Managed by container
Production Experience
Real scenario: CGLIB cannot proxy final
@Service
public class UserService {
public final void save() { } // final!
}
// @Transactional on save() will NOT work!
// CGLIB cannot override a final method
// -> Without transaction -> bug in production
When NOT to Make an Object a Bean
- DTO / Entity / Value Objects - these are regular data objects, created via
newor ORM - Local utilities - static methods do not require a bean
- Objects with short lifecycle - created and destroyed within a single request
Best Practices
- @Component/@Service for your own code
- @Bean for third-party libraries
- Remember about Proxy - final methods are not proxied (CGLIB creates a subclass, final cannot be overridden). In Spring Boot 2.2+ @Configuration can use
proxyBeanMethods = falseto disable CGLIB - this speeds up startup. - BeanDefinition can be modified via BeanFactoryPostProcessor
- Scanning is slow on large projects -> limit packages
Summary for Senior
- Bean = Spring-managed object
- BeanDefinition = meta-information for creation
- Proxy -> @Transactional, @Async, @Cacheable
- CGLIB -> subclass, does not proxy final
- JDK Proxy -> interfaces only
- BeanFactory -> heart of the container
Interview Cheat Sheet
Must know:
- Bean is an object managed by Spring Container (ApplicationContext): creates, injects dependencies, proxies, calls init/destroy
- You do not do
new Bean()- Spring does it via Reflection or CGLIB - BeanDefinition = bean “recipe”: class name, scope, dependencies, init/destroy methods
- Stereotype annotations:
@Component,@Service,@Repository,@Controller @Beanin@Configuration- for third-party libraries and complex configuration- Spring can wrap a bean in a Proxy for
@Transactional,@Async,@Cacheable - CGLIB cannot proxy
finalmethods -@Transactionalon them will not work - DTOs, Entities, Value Objects - should NOT be beans
Common follow-up questions:
- How does a Bean differ from a POJO? The same class can be a POJO (
new User()) or a Bean (created by Spring). The difference is who created it and who manages it. - When CGLIB vs JDK Dynamic Proxy? JDK Proxy - if there is an interface, CGLIB - if not. JDK proxies only interface methods.
- Can BeanDefinition be changed before creation? Yes, via
BeanFactoryPostProcessor. - Why does a
finalmethod not work with@Transactional? CGLIB creates a subclass,finalcannot be overridden - transaction will not be added.
Red flags (DO NOT say):
- “All objects should be beans” (DTOs, Entities, Value Objects are regular objects)
- “Spring Bean is a separate type of class” (Bean and POJO are not different class types, the difference is in management)
- ”
@Transactionalworks on any method” (not onfinal- CGLIB cannot override) - “Proxy is the same object” (Proxy is a wrapper that intercepts calls and adds behavior)
Related topics:
- [[01. What is Dependency Injection]]
- [[05. How to create a Bean in Spring]]
- [[06. What is Bean Lifecycle]]
- [[07. What are the Bean Lifecycle stages]]
- [[08. What is BeanPostProcessor]]