Clean • Professional
In Spring Boot, beans are created eagerly by default, meaning all singleton beans are instantiated at application startup.
The @Lazy annotation allows you to delay bean creation until the bean is actually needed.
In simple words:
@Lazy= Create the bean only when it is first used, not at startup.
@Lazy)By default, Spring uses eager initialization for singleton beans.
@Component
publicclassReportService {
publicReportService() {
System.out.println("ReportService created");
}
}
ReportService bean is created@Lazy DoesWhen a bean is marked with @Lazy:
Key Points:
@Lazy (Execution Flow)The internal steps when @Lazy is used are:

Example:
@Service
publicclassPaymentService {
publicPaymentService() {
System.out.println("PaymentService constructor called");
}
publicvoidprocessPayment() {
System.out.println("Payment processed");
}
}
@Service
publicclassOrderService {
@Autowired
@Lazy
private PaymentService paymentService;// Proxy injected here
publicvoidplaceOrder() {
System.out.println("Placing order...");
paymentService.processPayment();// Real bean created here
}
}
During application startup:
@PostConstruct is not called.Example with @PostConstruct:
@Service
@Lazy
publicclassPaymentService {
publicPaymentService() {
System.out.println("PaymentService constructor called");
}
@PostConstruct
publicvoidinit() {
System.out.println("PaymentService @PostConstruct called");
}
publicvoidprocessPayment() {
System.out.println("Payment processed");
}
}
Startup Output:
OrderServiceconstructor called
When the application first uses the bean:
@PostConstruct) are executedExample Usage:
@SpringBootApplication
publicclassApp {
publicstaticvoidmain(String[] args) {
ApplicationContextcontext= SpringApplication.run(App.class, args);
OrderServiceorderService= context.getBean(OrderService.class);
orderService.placeOrder();// Lazy bean created here
}
}
Output:
OrderService constructorcalled
Placing order...
PaymentService constructorcalled
PaymentService@PostConstructcalled
Payment processed
Application Startup
↓
@Lazy BeanNOT Created
↓
FirstMethodCallon Bean
↓
Real Bean Instance Created
↓
Dependencies Injected
↓
@PostConstruct Executed
↓
Method Execution Continues
@Lazy@Lazy is used to delay bean creation until it is first needed, improving startup performance, resolving circular dependencies, and controlling resource-heavy beans selectively.

@Lazy at Class LevelApplying @Lazy on a class makes the bean lazy everywhere, meaning it is created only when first accessed in the application, not at startup.
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
@Component
@Lazy
publicclassReportService {
publicReportService() {
System.out.println("Lazy ReportService created");
}
publicvoidgenerateReport() {
System.out.println("Generating report...");
}
}
Behavior:
@PostConstruct (if present) is executed after bean creation.Example:
ReportServicereportService= context.getBean(ReportService.class);
reportService.generateReport();
Output:
Lazy ReportService created
Generating report...
@Lazy at Injection Point (Field Injection)Applying @Lazy at a field delays the creation of that specific dependency; the containing bean is created at startup, but the lazy bean is instantiated only when first accessed.
@Service
publicclassOrderService {
@Autowired
@Lazy
private PaymentService paymentService;
publicvoidplaceOrder() {
paymentService.pay();
}
}
Behavior:
OrderService is created at startup.PaymentService is not created until placeOrder() is called.@Lazy with Constructor Injection (Recommended)When @Lazy is applied to a constructor parameter, the dependency is created only when first used, providing a clean, testable, and safe way to manage lazy beans.
@Service
publicclassOrderService {
privatefinal PaymentService paymentService;
publicOrderService(@Lazy PaymentService paymentService) {
this.paymentService = paymentService;
}
}
Advantages:
@Lazy with @Bean MethodsApplying @Lazy on a @Bean method delays the bean’s creation until it is explicitly requested from the application context, which is useful for heavy or resource-intensive beans.
@Configuration
publicclassAppConfig {
@Bean
@Lazy
public HeavyServiceheavyService() {
returnnewHeavyService();
}
}
Behavior:
Enabling spring.main.lazy-initialization=true makes all singleton beans lazy by default, improving startup time, but delays error detection, as configuration issues appear only at runtime.
spring.main.lazy-initialization=true
Behavior:
Risks:
Using @Lazy on one of the dependent beans lets Spring inject a proxy and delay bean creation, breaking the circular reference and allowing the application to start.
Problem Without @Lazy:
When two or more beans depend on each other, Spring cannot create them at startup, causing a circular dependency error and preventing the application from starting.
@Service
publicclassAService {
@Autowired
private BService bService;
}
@Service
publicclassBService {
@Autowired
private AService aService;
}
Temporary Fix Using @Lazy:
Applying @Lazy on one of the dependent beans allows Spring to inject a proxy and delay its creation, resolving the circular dependency at startup.
@Service
publicclassAService {
@Autowired
@Lazy
private BService bService;
}
@Service
publicclassBService {
@Autowired
private AService aService;
}
Behavior:
BService.@Lazy vs ObjectProvider (Advanced Usage)ObjectProvider allows explicit retrieval of a bean when needed, giving fine-grained control without hidden proxies, whereas @Lazy uses a proxy to delay creation automatically.
@Service
publicclassOrderService {
privatefinal ObjectProvider<PaymentService> provider;
publicOrderService(ObjectProvider<PaymentService> provider) {
this.provider = provider;
}
publicvoidplaceOrder() {
PaymentServicepaymentService= provider.getObject();
paymentService.pay();
}
}
Behavior:
@Lazy proxies.@Lazy with @TransactionalApplying @Lazy to transactional beans adds extra proxy layers on top of the existing @Transactional proxy, which can cause unexpected behavior. It’s best to keep transactional beans eager and use @Lazy only for non-critical or heavy beans.
Recommendation:
@Lazy only for heavy or helper beans.@Lazy with AOP (Aspects)Tip: Avoid @Lazy on critical AOP components.
@LazyErrors appear at runtime, not startup
@Lazy@Lazy@Lazy is a powerful Spring feature that helps optimize application startup time and memory usage by delaying bean creation until it is actually required.
However, @Lazy should be treated as an optimization tool, not a design fix. Overusing it can hide architectural issues, delay error detection, and make debugging more difficult.