MindIQ Academy

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

  1. What Is Spring Core?
  2. IoC and Dependency Injection
  3. Spring Container Overview
  4. BeanFactory
  5. ApplicationContext
  6. BeanFactory vs ApplicationContext
  7. Configuration Metadata
  8. Bean Definitions
  9. Bean Creation and Dependency Injection
  10. Bean Scopes
  11. Bean Lifecycle Flow
  12. Lifecycle Callback Methods
  13. BeanPostProcessor and BeanFactoryPostProcessor
  14. Component Scanning and Stereotypes
  15. Spring Boot 3 and Spring Framework 6 Notes
  16. Practical Examples
  17. Common Mistakes
  18. Certification Traps
  19. Interview Questions
  20. Summary Tables
  21. Quick Revision Notes
  22. 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 SpringSpring Core Solution
Manual object creation everywhereContainer creates beans
Tight coupling between classesDependency injection
Hard-to-test codeInterfaces and constructor injection
Complex lifecycle handlingBuilt-in lifecycle callbacks
Environment-specific configurationProfiles 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

TypeExampleRecommended?
Constructor injectionDependencies passed through constructorYes
Setter injectionDependencies passed through setter methodsSometimes
Field injectionDependencies injected directly into fieldsAvoid 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

InterfacePurpose
BeanFactoryBasic IoC container
ApplicationContextFull-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);

XmlBeanFactory is obsolete in modern Spring applications. Certification questions may still mention BeanFactory conceptually.

Characteristics

FeatureBeanFactory
Basic bean creationYes
Dependency injectionYes
Lazy initialization by defaultUsually yes
Enterprise featuresLimited
Common in Boot appsNo

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

ImplementationUse
AnnotationConfigApplicationContextJava annotation-based configuration
ClassPathXmlApplicationContextXML loaded from classpath
FileSystemXmlApplicationContextXML loaded from file system
WebApplicationContextWeb applications
ConfigurableApplicationContextSupports 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

FeatureBeanFactoryApplicationContext
Basic IoCYesYes
Dependency injectionYesYes
Bean lifecycleYesYes
Eager singleton creationNo, usually lazyYes, by default
EventsNoYes
InternationalizationNoYes
Resource loadingBasicAdvanced
Annotation supportLimited directlyFull
Used in Spring BootInternallyYes

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

SourceExample
XML configuration<bean id="service" class="..."/>
Java configuration@Configuration, @Bean
Annotation scanning@Component, @Service, @Repository
Spring Boot auto-configuration@SpringBootApplication, starters
External propertiesapplication.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.

ScopeMeaning
singletonOne shared instance per Spring container
prototypeNew instance every time requested
requestOne instance per HTTP request
sessionOne instance per HTTP session
applicationOne instance per ServletContext
websocketOne 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

StepWhat Happens
Metadata readingSpring learns what beans exist
Bean definition phaseSpring stores bean descriptions
InstantiationConstructor is called
Dependency injectionFields/properties/constructor args are set
Aware callbacksBean receives container-related objects if requested
Before initializationBeanPostProcessor can modify/wrap bean
Initialization@PostConstruct, afterPropertiesSet, init method
After initializationProxies are often created here
ReadyBean can be used
DestructionShutdown 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.*, not javax.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

ProcessorWorks OnRuns When
BeanFactoryPostProcessorBean definitionsBefore bean instantiation
BeanPostProcessorBean instancesBefore 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

AnnotationMeaning
@ComponentGeneric Spring-managed component
@ServiceService/business layer component
@RepositoryPersistence layer component; enables exception translation
@ControllerMVC controller
@RestControllerREST controller (@Controller + @ResponseBody)
@ConfigurationJava 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

AreaSpring 6 / Boot 3 Rule
Java versionJava 17+ required
Jakarta EEUses jakarta.* instead of javax.*
Native supportImproved AOT and GraalVM native image support
ObservabilityMicrometer-based observability improvements
ConfigurationAuto-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

MistakeCorrect Understanding
Thinking Spring creates every Java objectSpring manages only beans registered in the container
Using field injection everywherePrefer constructor injection
Expecting prototype injection into singleton to refresh automaticallyUse ObjectProvider, @Lookup, or scoped proxy
Forgetting @ComponentScan package rulesBoot scans from the main class package downward
Confusing BeanFactoryPostProcessor and BeanPostProcessorOne changes definitions, the other instances
Using javax.annotation.PostConstruct in Boot 3Use jakarta.annotation.PostConstruct
Assuming @Bean requires @Component on return type@Bean itself registers the bean
Assuming ApplicationContext and BeanFactory are identicalApplicationContext adds events, resources, i18n, eager singletons
Forgetting to close non-web contextsDestruction callbacks need context shutdown
Expecting @Primary to beat an explicit @Qualifier@Qualifier is more specific

18. Certification Traps

#Trap
1ApplicationContext eagerly creates singleton beans by default; BeanFactory is usually lazy.
2@Bean methods register beans even if the returned class has no stereotype annotation.
3Full @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.
5BeanFactoryPostProcessor runs before bean instances exist.
6BeanPostProcessor works on bean instances around initialization.
7@PostConstruct in Spring 6 comes from jakarta.annotation, not javax.annotation.
8Prototype beans receive initialization callbacks, but Spring does not manage their full destruction lifecycle.
9A 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.
13FactoryBean<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.
15Boot 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

AnnotationPurpose
@ComponentGeneric Spring bean
@ServiceService-layer bean
@RepositoryPersistence-layer bean with exception translation
@ControllerWeb MVC controller
@RestControllerREST controller
@ConfigurationJava config class
@BeanDeclares a bean from a method
@AutowiredDependency injection
@QualifierSelects a specific bean
@PrimaryMarks preferred bean
@ProfileRegisters bean only for active profile

Lifecycle Callback Summary

CallbackPhase
BeanFactoryPostProcessorBefore bean instantiation
ConstructorInstantiation
Dependency injectionPopulate properties/dependencies
Aware interfacesContainer callbacks
BeanPostProcessor.beforeBefore initialization
@PostConstructInitialization
InitializingBean.afterPropertiesSet()Initialization
custom initMethodInitialization
BeanPostProcessor.afterAfter initialization
@PreDestroyDestruction
DisposableBean.destroy()Destruction
custom destroyMethodDestruction

Spring 6 / Boot 3 Summary

TopicKey Point
Java baselineJava 17+
Jakarta namespaceUse jakarta.*
Native imageAOT support improved
Boot containerUses ApplicationContext
Auto-configurationConditional 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.
  • BeanFactory is the basic container; ApplicationContext is the full-featured container.
  • Configuration metadata can come from XML, Java config, annotations, Boot auto-configuration, and properties.
  • @Bean method name is the default bean name.
  • @Component class 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.
  • @Primary chooses a default bean; @Qualifier chooses a specific bean.
  • Bean lifecycle: definitions → instantiate → inject → aware → post-process → init → ready → destroy.
  • BeanFactoryPostProcessor changes definitions; BeanPostProcessor changes instances.
  • Spring 6 / Boot 3 uses jakarta.*, not javax.*.
  • @SpringBootApplication includes 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.