01 - Spring Core and IoC Notes
A beginner-to-advanced guide to Spring Core, the IoC container,
BeanFactory,ApplicationContext, bean lifecycle, and configuration metadata for Spring Professional Certification candidates. Covers Spring Framework 6 and Spring Boot 3 concepts.
Table of Contents
- What Is Spring Core?
- IoC and Dependency Injection
- Spring Container Overview
BeanFactoryApplicationContextBeanFactoryvsApplicationContext- Configuration Metadata
- Bean Definitions
- Bean Creation and Dependency Injection
- Bean Scopes
- Bean Lifecycle Flow
- Lifecycle Callback Methods
- BeanPostProcessor and BeanFactoryPostProcessor
- Component Scanning and Stereotypes
- Spring Boot 3 and Spring Framework 6 Notes
- Practical Examples
- Common Mistakes
- Certification Traps
- Interview Questions
- Summary Tables
- Quick Revision Notes
- One-Page Cheat Sheet
1. What Is Spring Core?
Spring Core is the foundation of the Spring Framework. It provides the container that creates objects, wires dependencies, manages lifecycle callbacks, and applies framework services such as configuration, profiles, events, and type conversion.
In normal Java, your code creates objects manually:
PaymentService service = new PaymentService(new EmailSender());
In Spring, the container creates and connects objects for you:
@Service
class PaymentService {
private final NotificationSender sender;
PaymentService(NotificationSender sender) {
this.sender = sender;
}
}
Why Spring Core Matters
| Problem Without Spring | Spring Core Solution |
|---|---|
| Manual object creation everywhere | Container creates beans |
| Tight coupling between classes | Dependency injection |
| Hard-to-test code | Interfaces and constructor injection |
| Complex lifecycle handling | Built-in lifecycle callbacks |
| Environment-specific configuration | Profiles and property sources |
2. IoC and Dependency Injection
Inversion of Control
IoC means the control of object creation moves from your application code to the Spring container.
Without IoC:
class OrderService {
private final EmailSender sender = new EmailSender();
}
With IoC:
class OrderService {
private final Sender sender;
OrderService(Sender sender) {
this.sender = sender;
}
}
The object does not create its dependency. It receives it.
Dependency Injection
Dependency Injection (DI) is the main technique Spring uses to implement IoC.
Application code asks for OrderService
|
v
Spring Container creates OrderService
|
v
Spring injects required Sender dependency
|
v
Ready-to-use bean is returned
Types of Dependency Injection
| Type | Example | Recommended? |
|---|---|---|
| Constructor injection | Dependencies passed through constructor | Yes |
| Setter injection | Dependencies passed through setter methods | Sometimes |
| Field injection | Dependencies injected directly into fields | Avoid for most application code |
Constructor Injection
@Service
class InvoiceService {
private final TaxCalculator calculator;
InvoiceService(TaxCalculator calculator) {
this.calculator = calculator;
}
}
Constructor injection is preferred because it makes required dependencies clear and supports immutable fields.
Setter Injection
@Service
class ReportService {
private Formatter formatter;
@Autowired
void setFormatter(Formatter formatter) {
this.formatter = formatter;
}
}
Setter injection is useful for optional dependencies.
Field Injection
@Service
class UserService {
@Autowired
private UserRepository repository;
}
Field injection works, but it is harder to test and hides required dependencies.
3. Spring Container Overview
The Spring container reads configuration metadata, creates beans, injects dependencies, manages lifecycle callbacks, and serves beans to the application.
Configuration Metadata
XML / Java Config / Annotations / Boot Auto-Configuration
|
v
Spring Container
|
+-------+--------+
| |
Bean Definitions Environment
|
v
Bean Creation -> Dependency Injection -> Lifecycle -> Ready Beans
Important Container Interfaces
| Interface | Purpose |
|---|---|
BeanFactory | Basic IoC container |
ApplicationContext | Full-featured container used in modern applications |
4. BeanFactory
BeanFactory is the simplest Spring IoC container. It knows how to create and manage beans.
BeanFactory factory = new XmlBeanFactory(new ClassPathResource("beans.xml"));
MyService service = factory.getBean(MyService.class);
XmlBeanFactoryis obsolete in modern Spring applications. Certification questions may still mentionBeanFactoryconceptually.
Characteristics
| Feature | BeanFactory |
|---|---|
| Basic bean creation | Yes |
| Dependency injection | Yes |
| Lazy initialization by default | Usually yes |
| Enterprise features | Limited |
| Common in Boot apps | No |
BeanFactory is mainly important for understanding Spring internals.
5. ApplicationContext
ApplicationContext extends BeanFactory and adds many enterprise features.
ApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class);
PaymentService service = context.getBean(PaymentService.class);
Common Implementations
| Implementation | Use |
|---|---|
AnnotationConfigApplicationContext | Java annotation-based configuration |
ClassPathXmlApplicationContext | XML loaded from classpath |
FileSystemXmlApplicationContext | XML loaded from file system |
WebApplicationContext | Web applications |
ConfigurableApplicationContext | Supports refresh and close operations |
Extra Features
ApplicationContext provides:
- Eager singleton bean creation by default
- Internationalization through
MessageSource - Event publishing
- Resource loading
- Environment and profiles
- Integration with annotation processing
- Application startup and shutdown lifecycle support
6. BeanFactory vs ApplicationContext
| Feature | BeanFactory | ApplicationContext |
|---|---|---|
| Basic IoC | Yes | Yes |
| Dependency injection | Yes | Yes |
| Bean lifecycle | Yes | Yes |
| Eager singleton creation | No, usually lazy | Yes, by default |
| Events | No | Yes |
| Internationalization | No | Yes |
| Resource loading | Basic | Advanced |
| Annotation support | Limited directly | Full |
| Used in Spring Boot | Internally | Yes |
Certification Rule
For real applications and certification scenarios, assume ApplicationContext is the standard container unless the question specifically says BeanFactory.
7. Configuration Metadata
Configuration metadata tells Spring which beans to create and how to wire them.
Main Sources
| Source | Example |
|---|---|
| XML configuration | <bean id="service" class="..."/> |
| Java configuration | @Configuration, @Bean |
| Annotation scanning | @Component, @Service, @Repository |
| Spring Boot auto-configuration | @SpringBootApplication, starters |
| External properties | application.properties, application.yml |
Java Configuration
@Configuration
class AppConfig {
@Bean
DataSource dataSource() {
return new HikariDataSource();
}
@Bean
UserService userService(UserRepository repository) {
return new UserService(repository);
}
}
XML Configuration
<beans>
<bean id="userRepository" class="com.example.UserRepository"/>
<bean id="userService" class="com.example.UserService">
<constructor-arg ref="userRepository"/>
</bean>
</beans>
Annotation Configuration
@Service
class UserService {
private final UserRepository repository;
UserService(UserRepository repository) {
this.repository = repository;
}
}
@Repository
class UserRepository {
}
8. Bean Definitions
A bean definition is Spring's internal description of a bean.
It contains metadata such as:
- Bean class
- Scope
- Constructor arguments
- Property values
- Lazy initialization flag
- Init and destroy methods
- Primary flag
- Qualifiers
- Dependencies
@Bean / @Component / XML
|
v
BeanDefinition
|
v
Spring uses it to create the actual bean instance
Bean Name
By default, Spring derives a bean name from the class name:
@Service
class PaymentService {
}
Default bean name:
paymentService
For @Bean methods, the method name is the default bean name:
@Bean
OrderService orderService() {
return new OrderService();
}
Default bean name:
orderService
9. Bean Creation and Dependency Injection
How Spring Resolves Dependencies
For @Autowired and constructor injection, Spring usually resolves dependencies by type.
@Service
class CheckoutService {
CheckoutService(PaymentGateway gateway) {
}
}
Spring looks for a bean of type PaymentGateway.
Multiple Bean Candidates
If multiple beans match the same type, Spring needs help.
interface PaymentGateway {
}
@Component
class StripeGateway implements PaymentGateway {
}
@Component
class PaypalGateway implements PaymentGateway {
}
This injection is ambiguous:
@Service
class CheckoutService {
CheckoutService(PaymentGateway gateway) {
}
}
Spring may throw NoUniqueBeanDefinitionException.
@Primary
@Primary
@Component
class StripeGateway implements PaymentGateway {
}
@Primary marks the default candidate when multiple beans match.
@Qualifier
@Service
class CheckoutService {
CheckoutService(@Qualifier("paypalGateway") PaymentGateway gateway) {
}
}
@Qualifier selects a specific bean.
Dependency Resolution Order
Find beans by type
|
v
If one match -> inject it
|
v
If multiple -> check @Qualifier
|
v
If no qualifier -> check @Primary
|
v
If still ambiguous -> error
10. Bean Scopes
Bean scope controls how many instances Spring creates and how long they live.
| Scope | Meaning |
|---|---|
singleton | One shared instance per Spring container |
prototype | New instance every time requested |
request | One instance per HTTP request |
session | One instance per HTTP session |
application | One instance per ServletContext |
websocket | One instance per WebSocket session |
Singleton Scope
@Component
class AuditService {
}
Default scope is singleton.
AuditService a = context.getBean(AuditService.class);
AuditService b = context.getBean(AuditService.class);
System.out.println(a == b); // true
Prototype Scope
@Scope("prototype")
@Component
class ReportBuilder {
}
ReportBuilder a = context.getBean(ReportBuilder.class);
ReportBuilder b = context.getBean(ReportBuilder.class);
System.out.println(a == b); // false
Prototype in Singleton Trap
@Service
class SingletonService {
private final PrototypeBean prototype;
SingletonService(PrototypeBean prototype) {
this.prototype = prototype;
}
}
The prototype is injected once when the singleton is created. It does not automatically become a new prototype on every method call.
Solutions include:
ObjectProvider<PrototypeBean>Provider<PrototypeBean>@Lookup- Scoped proxies
@Service
class SingletonService {
private final ObjectProvider<PrototypeBean> provider;
SingletonService(ObjectProvider<PrototypeBean> provider) {
this.provider = provider;
}
PrototypeBean newPrototype() {
return provider.getObject();
}
}
11. Bean Lifecycle Flow
The bean lifecycle is one of the most important certification topics.
1. Container starts
|
v
2. Read configuration metadata
|
v
3. Create BeanDefinition objects
|
v
4. Run BeanFactoryPostProcessor
|
v
5. Instantiate bean
|
v
6. Populate dependencies
|
v
7. Aware callbacks
|
v
8. BeanPostProcessor before initialization
|
v
9. Initialization callbacks
|-- @PostConstruct
|-- InitializingBean.afterPropertiesSet()
|-- custom init-method
|
v
10. BeanPostProcessor after initialization
|
v
11. Bean ready for use
|
v
12. Container shuts down
|
v
13. Destruction callbacks
|-- @PreDestroy
|-- DisposableBean.destroy()
|-- custom destroy-method
Lifecycle in Simple Words
| Step | What Happens |
|---|---|
| Metadata reading | Spring learns what beans exist |
| Bean definition phase | Spring stores bean descriptions |
| Instantiation | Constructor is called |
| Dependency injection | Fields/properties/constructor args are set |
| Aware callbacks | Bean receives container-related objects if requested |
| Before initialization | BeanPostProcessor can modify/wrap bean |
| Initialization | @PostConstruct, afterPropertiesSet, init method |
| After initialization | Proxies are often created here |
| Ready | Bean can be used |
| Destruction | Shutdown callbacks run |
12. Lifecycle Callback Methods
@PostConstruct and @PreDestroy
Spring Framework 6 uses the Jakarta annotations:
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
@Component
class CacheService {
@PostConstruct
void init() {
System.out.println("Cache initialized");
}
@PreDestroy
void cleanup() {
System.out.println("Cache cleaned");
}
}
In Spring 6 / Boot 3, use
jakarta.annotation.*, notjavax.annotation.*.
InitializingBean and DisposableBean
@Component
class Worker implements InitializingBean, DisposableBean {
@Override
public void afterPropertiesSet() {
System.out.println("Initialized");
}
@Override
public void destroy() {
System.out.println("Destroyed");
}
}
Custom Init and Destroy Methods
@Bean(initMethod = "start", destroyMethod = "stop")
Engine engine() {
return new Engine();
}
Initialization Order
@PostConstruct
|
v
InitializingBean.afterPropertiesSet()
|
v
custom init-method
Destruction Order
@PreDestroy
|
v
DisposableBean.destroy()
|
v
custom destroy-method
13. BeanPostProcessor and BeanFactoryPostProcessor
BeanFactoryPostProcessor
Runs after bean definitions are loaded but before beans are instantiated.
@Component
class MyFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
System.out.println("Can modify bean definitions here");
}
}
Use it to modify metadata, not bean instances.
BeanPostProcessor
Runs around initialization of each bean instance.
@Component
class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
return bean;
}
}
Use it to wrap, proxy, or modify actual bean instances.
Key Difference
| Processor | Works On | Runs When |
|---|---|---|
BeanFactoryPostProcessor | Bean definitions | Before bean instantiation |
BeanPostProcessor | Bean instances | Before and after initialization |
Common Internal Uses
Spring itself uses post-processors for:
@Autowired@Value@PostConstruct- AOP proxies
- Configuration class processing
- Event listener processing
14. Component Scanning and Stereotypes
Component scanning finds classes annotated with stereotype annotations and registers them as beans.
Stereotype Annotations
| Annotation | Meaning |
|---|---|
@Component | Generic Spring-managed component |
@Service | Service/business layer component |
@Repository | Persistence layer component; enables exception translation |
@Controller | MVC controller |
@RestController | REST controller (@Controller + @ResponseBody) |
@Configuration | Java configuration class |
@SpringBootApplication
class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
@SpringBootApplication includes:
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
Component Scan Rule
By default, Spring Boot scans from the package of the main application class downward.
com.example
App.java -> @SpringBootApplication here
service/UserService -> scanned
repository/UserRepo -> scanned
com.other
OtherService -> not scanned by default
15. Spring Boot 3 and Spring Framework 6 Notes
Spring Boot 3 is based on Spring Framework 6.
Important Changes
| Area | Spring 6 / Boot 3 Rule |
|---|---|
| Java version | Java 17+ required |
| Jakarta EE | Uses jakarta.* instead of javax.* |
| Native support | Improved AOT and GraalVM native image support |
| Observability | Micrometer-based observability improvements |
| Configuration | Auto-configuration imports use modern metadata |
Jakarta Example
import jakarta.annotation.PostConstruct;
import jakarta.validation.constraints.NotBlank;
import jakarta.servlet.http.HttpServletRequest;
Old imports like these are wrong in Boot 3 applications:
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
AOT and Native Image
Spring Boot 3 supports Ahead-of-Time processing for native images.
In simple terms:
- The application is analyzed at build time.
- Reflection and proxy needs are discovered early.
- Native image startup can be much faster.
- Dynamic runtime behavior may require hints.
Certification trap: AOT improves native-image support, but it does not remove the IoC container model.
16. Practical Examples
Example 1: Constructor Injection with @Service
interface EmailClient {
void send(String message);
}
@Component
class SmtpEmailClient implements EmailClient {
public void send(String message) {
System.out.println("Sending: " + message);
}
}
@Service
class NotificationService {
private final EmailClient emailClient;
NotificationService(EmailClient emailClient) {
this.emailClient = emailClient;
}
void notifyUser() {
emailClient.send("Welcome");
}
}
Example 2: @Configuration and @Bean
@Configuration
class BillingConfig {
@Bean
CurrencyService currencyService() {
return new CurrencyService();
}
@Bean
BillingService billingService(CurrencyService currencyService) {
return new BillingService(currencyService);
}
}
In a full @Configuration class, Spring enhances the class so calls to @Bean methods preserve singleton semantics.
Example 3: Profiles
@Profile("dev")
@Bean
DataSource devDataSource() {
return new EmbeddedDatabaseBuilder().build();
}
@Profile("prod")
@Bean
DataSource prodDataSource() {
return productionDataSource();
}
Only beans matching the active profile are registered.
Example 4: Conditional Beans
@Bean
@ConditionalOnMissingBean
PaymentGateway paymentGateway() {
return new DefaultPaymentGateway();
}
In Spring Boot auto-configuration, conditions allow default beans to back off when the user provides their own bean.
17. Common Mistakes
| Mistake | Correct Understanding |
|---|---|
| Thinking Spring creates every Java object | Spring manages only beans registered in the container |
| Using field injection everywhere | Prefer constructor injection |
| Expecting prototype injection into singleton to refresh automatically | Use ObjectProvider, @Lookup, or scoped proxy |
Forgetting @ComponentScan package rules | Boot scans from the main class package downward |
Confusing BeanFactoryPostProcessor and BeanPostProcessor | One changes definitions, the other instances |
Using javax.annotation.PostConstruct in Boot 3 | Use jakarta.annotation.PostConstruct |
Assuming @Bean requires @Component on return type | @Bean itself registers the bean |
Assuming ApplicationContext and BeanFactory are identical | ApplicationContext adds events, resources, i18n, eager singletons |
| Forgetting to close non-web contexts | Destruction callbacks need context shutdown |
Expecting @Primary to beat an explicit @Qualifier | @Qualifier is more specific |
18. Certification Traps
| # | Trap |
|---|---|
| 1 | ApplicationContext eagerly creates singleton beans by default; BeanFactory is usually lazy. |
| 2 | @Bean methods register beans even if the returned class has no stereotype annotation. |
| 3 | Full @Configuration classes are proxied to preserve singleton semantics for inter-bean calls. |
| 4 | @Component classes with @Bean methods are not the same as full proxied @Configuration classes. |
| 5 | BeanFactoryPostProcessor runs before bean instances exist. |
| 6 | BeanPostProcessor works on bean instances around initialization. |
| 7 | @PostConstruct in Spring 6 comes from jakarta.annotation, not javax.annotation. |
| 8 | Prototype beans receive initialization callbacks, but Spring does not manage their full destruction lifecycle. |
| 9 | A singleton depending directly on a prototype receives only one prototype instance at singleton creation time. |
| 10 | @Qualifier resolves ambiguity more specifically than @Primary. |
| 11 | @Repository has persistence exception translation semantics. |
| 12 | @SpringBootApplication includes component scanning only from its package downward by default. |
| 13 | FactoryBean<T> produces an object; prefix bean name with & to get the factory itself. |
| 14 | @Value can use property placeholders and SpEL, but missing properties may fail unless defaults are provided. |
| 15 | Boot auto-configuration is conditional and backs off when user-defined beans are present. |
19. Interview Questions
Q1. What is IoC in Spring?
IoC means Spring controls object creation and dependency wiring instead of application code manually constructing dependencies.
Q2. What is dependency injection?
Dependency injection is the process of supplying an object with its required dependencies, commonly through constructor, setter, or field injection.
Q3. Why is constructor injection recommended?
It makes required dependencies explicit, supports immutability, and improves testability.
Q4. What is the difference between BeanFactory and ApplicationContext?
BeanFactory is the basic IoC container. ApplicationContext extends it and adds events, i18n, resource loading, environment support, and eager singleton creation.
Q5. What is a bean definition?
A bean definition is Spring's internal metadata describing how to create and configure a bean.
Q6. What are common Spring bean scopes?
singleton, prototype, request, session, application, and websocket.
Q7. What is the default bean scope?
singleton — one shared instance per Spring container.
Q8. What is the bean lifecycle order?
Bean definition loading, factory post-processing, instantiation, dependency injection, aware callbacks, post-processors, initialization callbacks, ready state, and destruction callbacks.
Q9. What is the difference between BeanPostProcessor and BeanFactoryPostProcessor?
BeanFactoryPostProcessor modifies bean definitions before objects are created. BeanPostProcessor works on bean instances before and after initialization.
Q10. What is @Configuration used for?
It marks a class as a source of bean definitions and enables special proxying behavior for @Bean methods.
Q11. What does @SpringBootApplication include?
It combines @SpringBootConfiguration, @EnableAutoConfiguration, and @ComponentScan.
Q12. What changed in Spring 6 / Boot 3 regarding Jakarta EE?
Spring moved from javax.* packages to jakarta.* packages for Jakarta EE APIs.
20. Summary Tables
Core Annotation Summary
| Annotation | Purpose |
|---|---|
@Component | Generic Spring bean |
@Service | Service-layer bean |
@Repository | Persistence-layer bean with exception translation |
@Controller | Web MVC controller |
@RestController | REST controller |
@Configuration | Java config class |
@Bean | Declares a bean from a method |
@Autowired | Dependency injection |
@Qualifier | Selects a specific bean |
@Primary | Marks preferred bean |
@Profile | Registers bean only for active profile |
Lifecycle Callback Summary
| Callback | Phase |
|---|---|
BeanFactoryPostProcessor | Before bean instantiation |
| Constructor | Instantiation |
| Dependency injection | Populate properties/dependencies |
| Aware interfaces | Container callbacks |
BeanPostProcessor.before | Before initialization |
@PostConstruct | Initialization |
InitializingBean.afterPropertiesSet() | Initialization |
custom initMethod | Initialization |
BeanPostProcessor.after | After initialization |
@PreDestroy | Destruction |
DisposableBean.destroy() | Destruction |
custom destroyMethod | Destruction |
Spring 6 / Boot 3 Summary
| Topic | Key Point |
|---|---|
| Java baseline | Java 17+ |
| Jakarta namespace | Use jakarta.* |
| Native image | AOT support improved |
| Boot container | Uses ApplicationContext |
| Auto-configuration | Conditional and classpath-driven |
21. Quick Revision Notes
- Spring Core provides IoC, DI, bean creation, lifecycle management, and configuration support.
- IoC means Spring controls object creation and wiring.
- DI is how dependencies are supplied to objects.
- Prefer constructor injection for required dependencies.
BeanFactoryis the basic container;ApplicationContextis the full-featured container.- Configuration metadata can come from XML, Java config, annotations, Boot auto-configuration, and properties.
@Beanmethod name is the default bean name.@Componentclass name becomes a decapitalized bean name by default.- Default scope is
singleton. - Prototype beans are created on demand, but destruction is not fully managed like singleton beans.
@Primarychooses a default bean;@Qualifierchooses a specific bean.- Bean lifecycle: definitions → instantiate → inject → aware → post-process → init → ready → destroy.
BeanFactoryPostProcessorchanges definitions;BeanPostProcessorchanges instances.- Spring 6 / Boot 3 uses
jakarta.*, notjavax.*. @SpringBootApplicationincludes configuration, auto-configuration, and component scanning.
22. One-Page Cheat Sheet
====================== SPRING CORE & IOC CHEAT SHEET ======================
IOC / DI
IoC = Spring controls object creation
DI = dependencies supplied to objects
Prefer constructor injection for required dependencies
CONTAINERS
BeanFactory = basic IoC container, usually lazy
ApplicationContext = BeanFactory + events + i18n + resources + env
ApplicationContext eagerly creates singleton beans by default
CONFIGURATION METADATA
XML: <bean>
Java config: @Configuration + @Bean
Annotation: @Component/@Service/@Repository
Boot: @SpringBootApplication + auto-configuration
Properties: application.properties / application.yml
BEAN NAMES
@Bean method -> method name
@Component class PaymentService -> paymentService
INJECTION
by type first
multiple candidates -> @Qualifier / @Primary
@Qualifier is more specific than @Primary
SCOPES
singleton = one per container (default)
prototype = new instance each request
web scopes = request/session/application/websocket
prototype injected into singleton = injected once only
LIFECYCLE
read metadata -> BeanDefinition
BeanFactoryPostProcessor
instantiate -> inject dependencies -> aware callbacks
BeanPostProcessor.before
@PostConstruct -> InitializingBean -> init-method
BeanPostProcessor.after
bean ready
@PreDestroy -> DisposableBean -> destroy-method
POST-PROCESSORS
BeanFactoryPostProcessor = modifies bean definitions before instances
BeanPostProcessor = modifies/wraps bean instances before/after init
SPRING 6 / BOOT 3
Java 17+
jakarta.* instead of javax.*
@SpringBootApplication =
@SpringBootConfiguration + @EnableAutoConfiguration + @ComponentScan
Boot auto-config is conditional and backs off for user beans
AOT/native image support improved
TRAPS
@Bean does not require @Component on returned class
full @Configuration classes are proxied
BeanFactoryPostProcessor runs before bean creation
BeanPostProcessor runs around initialization
prototype destruction is not fully managed
component scanning starts from main app package downward
use jakarta.annotation.PostConstruct in Spring 6 / Boot 3
===========================================================================
End of 01 - Spring Core and IoC Notes.