Tao
Tao

Spring Bean Singleton and Prototype

When using the Spring framework to build enterprise-level applications, understanding and correctly using different Bean scopes is crucial. The framework provides various scopes, with the most commonly used being Spring Singleton and Prototype. This article will help you understand the differences between these two scopes and their use cases through simple examples.

The Spring container creates a single instance of a Bean for each Spring IoC container. This means that no matter how many times we request it, Spring will provide the same Bean instance. This is suitable for stateless services or services that need to share state, such as configuration services or data access objects (DAOs).

java

import org.springframework.stereotype.Component;
@Component
public class SingletonService {
    public SingletonService() {
        System.out.println("SingletonService instance created.");
    }
    public void serve() {
        System.out.println("Serving with SingletonService.");
    }
}

In the above example, the Spring container will create only one instance of the SingletonService class.

In contrast to the singleton, the prototype scope creates a new Bean instance every time it is requested. This is suitable for Beans that have state, where each Bean instance needs a different state. In this scope, the Spring container does not manage the complete lifecycle of the Bean; once the Bean is created and initialized, it is handed over to the client code.

java

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope("prototype")
public class PrototypeService {
    public PrototypeService() {
        System.out.println("PrototypeService instance created.");
    }
    public void serve() {
        System.out.println("Serving with PrototypeService.");
    }
}

Here, a new instance of PrototypeService will be created every time it is requested.

We can observe the behavioral differences between the two scopes in the following Spring application main class:

java

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class SpringDemoApplication {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        // Singleton scope
        SingletonService singleton1 = context.getBean(SingletonService.class);
        SingletonService singleton2 = context.getBean(SingletonService.class);
        System.out.println("Are singleton beans the same? " + (singleton1 == singleton2));
        // Prototype scope
        PrototypeService prototype1 = context.getBean(PrototypeService.class);
        PrototypeService prototype2 = context.getBean(PrototypeService.class);
        System.out.println("Are prototype beans the same? " + (prototype1 == prototype2));
    }
}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
}

In this example, the two instances of SingletonService are the same, while each request for PrototypeService creates a new instance.

Understanding the singleton and prototype scopes and their applications in Spring applications is essential for creating efficient and maintainable applications. Choosing the correct Bean scope can significantly impact the application’s behavior and performance. Through the examples provided, you should now have a better understanding of these two scopes and how to apply them in real-world projects. The code for this article can be found on Github.

Related Content