How Spring Boot Creates Beans (Bean Lifecycle Simplified for Production)

Understanding how Spring Boot creates and manages beans is one of the most powerful tools in a developer’s arsenal — especially in production systems.

This guide explains the bean creation process in Spring Boot in simple language with real-world insights that help you diagnose issues like:

  • BeanCreationException
  • Missing beans
  • Proxy behavior
  • Initialization failures
  • Unexpected lifecycle interactions

Whether you are a beginner or architecting large systems, this article will give you a clear mental model of Spring’s bean lifecycle.

What Is a Spring Bean?

A Spring bean is simply an object that Spring manages — from construction to destruction.

Beans have:

  • Identity — unique instance per container
  • Lifecycle — created, initialized, injected, destroyed
  • Scope — singleton, prototype, request, session, etc.

Spring Boot manages beans for:

  • Components (@Component, @Service, @Repository, @Controller)
  • Manual beans (@Bean methods)
  • Auto-configured beans provided by Spring Boot

If you want to understand how these beans are detected, see:
https://springbootfixes.com/spring-boot-application-starts-startup-flow-explained/

Bean Discovery — How Spring Finds Beans

Spring Boot finds beans through:

Component Scanning

Spring scans packages starting from your main application class (root package).
It detects annotations like:

  • @Component
  • @Service
  • @Repository
  • @Controller
  • @Configuration

Any class annotated as above becomes a bean definition.

Auto-Configuration

Spring Boot auto-configuration adds many beans based on classpath and conditions.
These are defined in Spring Boot starter libraries.

Manual Bean Definitions

You can define beans explicitly using @Bean inside @Configuration classes.

Manual beans have full lifecycle semantics with interception and proxying.

For a deep dive on configuration and @Configuration/@Bean, see:
https://springbootfixes.com/configuration-and-bean-in-spring-boot-deep-but-clear-explanation/

Bean Definition → Bean Instance

Once Spring knows which classes define beans, it creates bean definitions.

These definitions include:

  • Bean type
  • Scope
  • Dependencies
  • Initialization/destruction callbacks
  • Qualifiers, names, and aliases

Spring then resolves these definitions to actual bean instances.

Bean Instantiation

Spring creates a bean instance using:

Constructor Injection (Recommended)

If your bean has a constructor with arguments, Spring resolves dependencies and uses that constructor:

@Service
public class OrderService {
public OrderService(PaymentService paymentService) { … }
}

Constructor injection ensures immutability and clear dependencies — ideal in production.

Default No-Arg Constructor

If no constructor is provided, Spring uses the default no-args constructor.

Factory Method (@Bean)

Beans created via @Bean are instantiated through factory methods in configuration classes.

Dependency Resolution

Once instantiated, Spring resolves dependencies:

  • Constructor parameters
  • @Autowired fields or setters
  • @Qualifier or @Primary resolution

Spring uses type first, then qualifiers, then primary beans to resolve ambiguities.

If a dependency cannot be resolved, Spring throws:

BeanCreationException: NoSuchBeanDefinitionException

Understanding this helps when diagnosing startup failures:
https://springbootfixes.com/beancreationexception-in-spring-boot-common-causes-and-fix/

BeanPostProcessor and Initialization

Spring supports bean post-processing, allowing beans to be modified before and after initialization.

Common scenarios:

  • AOP proxies (@Transactional, @Async)
  • Custom post-processors
  • JPA entity listeners
  • Validation

The lifecycle progression:

  1. Instantiate bean
  2. Populate dependencies
  3. Apply post-processors before initialization
  4. Call @PostConstruct / init methods
  5. Apply post-processors after initialization

These steps matter in production when:

  • You rely on proxies
  • You integrate with cross-cutting concerns
  • You hook lifecycle events

Bean Scopes Matter

Spring supports multiple scopes:

Singleton (default)

One instance per application context — widely used in backend services.

Prototype

New instance on each request — useful for stateful objects.

Request / Session

Relevant in web applications.

For most backend services, singleton scope is recommended unless state is required.

Circular Dependencies and How Spring Handles Them

If two beans depend on each other:

@Service
public class A { public A(B b) { … } }
@Service
public class B { public B(A a) { … } }

Spring can sometimes resolve circular references using proxies — but constructor injection makes them impossible to resolve.

In production systems:

  • Avoid circular dependencies
  • Refactor to break cycles
  • Use event messaging instead of direct injection

Proxies, AOP and Lifecycle

Spring uses proxies to implement:

  • Transactions (@Transactional)
  • Caching (@Cacheable)
  • Security advice
  • Asynchronous methods (@Async)

Proxy types:

  • JDK dynamic proxies
  • CGLIB proxies

Proxies wrap your beans after creation but before usage — often via BeanPostProcessors.

Understanding proxies helps when debugging issues like:

  • Methods not being called
  • Unexpected behavior in nested calls

Destruction and Cleanup

Beans that require cleanup can use:

  • @PreDestroy
  • DisposableBean
  • Custom destroy methods

Spring invokes these when the application context shuts down — useful for:

  • Closing connections
  • Releasing resources
  • Stopping background threads

Production Tips & Best Practices

✔ Prefer constructor injection
✔ Avoid field injection
✔ Break circular dependencies early
✔ Define minimal initialization logic
✔ Avoid heavy work in constructors / init methods
✔ Log bean creation issues early with DEBUG logging
✔ Understand auto-configuration priorities

Production systems benefit when lifecycle behavior is predictable and testable.

Internal Links for Deeper Context

Frequently Asked Questions

What triggers bean creation in Spring Boot?

Beans are created during application startup when Spring scans configurations, components, and manual definitions.

How do I see which beans are created?

Enable debug logging or inspect the application context in code.

What if I need a bean only in certain environments?

Use @Profile on beans or configuration classes to load them only when a specific profile is active.

Why does Spring create proxy beans?

Proxies provide additional behavior like transactions, logging, security, and caching.

Summary — Your Bean Lifecycle Mental Model

  1. Spring scans for bean definitions
  2. It builds bean metadata
  3. Instances are created and dependencies injected
  4. Post-processors wrap beans
  5. Initialization callbacks run
  6. Proxies are applied
  7. Application is ready to serve requests
  8. Destruction callbacks occur on shutdown

This flow helps you debug complex issues and architect resilient applications.

Leave a Comment

Your email address will not be published. Required fields are marked *