Create a new instance of component in Spring Boot/Framework
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Spring manages beans as singletons by default — every @Autowired injection receives the same instance. When you need a new instance of a component each time, use @Scope("prototype") on the bean, ObjectFactory<T> or ObjectProvider<T> for lazy retrieval, ApplicationContext.getBean() for manual lookup, or @Lookup for method injection. Each approach has different trade-offs for testability, thread safety, and coupling to the Spring framework.
Default Singleton Scope
By default, Spring creates one instance of NotificationService shared across all injection points. The count field accumulates across all requests.
Method 1: Prototype Scope with ObjectProvider
@Scope("prototype") tells Spring to create a new instance for each request. ObjectProvider<T> lazily retrieves a new instance when getObject() is called, avoiding the common pitfall of injecting a prototype into a singleton (which would give you the same instance).
Method 2: ApplicationContext.getBean()
ApplicationContext.getBean() creates a new instance for prototype-scoped beans. This works but couples your code to the Spring API, making unit testing harder.
Method 3: @Lookup Method Injection
@Lookup tells Spring to override the abstract method with a bean-lookup implementation at runtime via CGLIB subclassing. The service class must be non-final (or abstract).
Method 4: @Bean Factory Method
A Supplier<T> factory bean provides a clean, framework-agnostic way to create new instances. The calling code has no Spring dependency.
Request Scope (Web Applications)
SCOPE_REQUEST creates a new instance per HTTP request. proxyMode = TARGET_CLASS generates a CGLIB proxy so the singleton controller can hold a reference that delegates to the correct request-scoped instance.
Common Pitfalls
- Injecting prototype into singleton directly:
@Autowired private MyPrototype bean;in a singleton gives you one instance forever. The prototype scope only creates a new instance when the container is asked — useObjectProvider,@Lookup, or a factory. - Forgetting
@Scope("prototype")on the class: Without the scope annotation,getBean()andObjectProviderstill return the same singleton instance. Both the retrieval mechanism and the scope annotation are required. - CGLIB proxy requirements:
@Lookuprequires the class to be non-final and the method to be non-private.ScopedProxyMode.TARGET_CLASSrequires CGLIB on the classpath (included in Spring Boot by default). - Prototype beans not destroyed by Spring: Spring does not manage the lifecycle of prototype beans after creation —
@PreDestroymethods are never called. You must clean up resources manually. - Thread safety assumptions: Creating new instances per request is safer for mutable state, but adds garbage collection overhead. For stateless services, singleton scope is more efficient.
Summary
@Scope("prototype")— marks a bean for new-instance-per-request creationObjectProvider<T>.getObject()— cleanest way to get prototype instances (recommended)@Lookup— method injection via abstract method, Spring generates the implementationApplicationContext.getBean()— works but couples code to Spring APISupplier<T>factory bean — framework-agnostic approach for testability@Scope(SCOPE_REQUEST)withproxyMode— new instance per HTTP request in web apps

