ZetCode

Spring Singleton scope bean

last modified October 18, 2023

Spring Singleton scoped bean tutorial shows how to use a Singleton scoped bean in a Spring application.

Spring is a popular Java application framework for creating enterprise applications.

Spring Singleton bean

Singleton beans are created when the Spring container is created and are destroyed when the container is destroyed. Singleton beans are shared; only one instance of a singleton bean is created per Spring container. Singleton scope is the default scope for a Spring bean.

Other bean scopes are: prototype, request, session, global session, and application.

Spring Singleton bean example

The application creates two singleton scoped beans and checks if they are identical. The application is a classic Spring 5 console application.

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
            http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zetcode</groupId>
    <artifactId>scopesingletonex</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <spring-version>5.3.23</spring-version>

    </properties>

    <dependencies>

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.4.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring-version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring-version}</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>3.1.0</version>
                <configuration>
                    <mainClass>com.zetcode.Application</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

In the pom.xml file, we have basic Spring dependencies spring-core and spring-context and logging logback-classic dependency.

The exec-maven-plugin is used for executing Spring application from the Maven on the command line.

resources/my.properties
myapp.name=ScopeSingleton
myapp.author=Jan Bodnar

We have two basic properties in the my.properties file. They are using in the Message bean.

resources/logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <logger name="org.springframework" level="ERROR"/>
    <logger name="com.zetcode" level="INFO"/>

    <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <Pattern>%d{HH:mm:ss.SSS} [%thread] %blue(%-5level) %magenta(%logger{36}) - %msg %n
            </Pattern>
        </encoder>
    </appender>

    <root>
        <level value="INFO" />
        <appender-ref ref="consoleAppender" />
    </root>
</configuration>

The logback.xml is a configuration file for the Logback logging library.

com/zetcode/bean/Message.java
package com.zetcode.bean;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope("singleton") // change to prototype
@PropertySource("classpath:my.properties")
public class Message {

    @Value("${myapp.name}")
    private String name;

    @Value("${myapp.author}")
    private String author;

    public String getMessage() {

        return String.format("Application %s was created by %s", name, author);
    }
}

The Message is a Spring bean managed by the Spring container. It has singleton scope.

@Component
@Scope("singleton") // change to prototype
@PropertySource("classpath:my.properties")
public class Message {

The @Scope("singleton") annotation is not necessary; the default scope is singleton if not specified. With the @PropertySource annotation we specify the properties file. The properties are later read with @Value.

com/zetcode/Application.java
package com.zetcode;

import com.zetcode.bean.Message;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan(basePackages = "com.zetcode")
public class Application {

    private static final Logger logger = LoggerFactory.getLogger(Application.class);

    public static void main(String[] args) {

        var ctx = new AnnotationConfigApplicationContext(Application.class);

        var app = ctx.getBean(Application.class);

        var bean1 = ctx.getBean(Message.class);
        var bean2 = ctx.getBean(Message.class);

        app.run(bean1, bean2);

        ctx.close();
    }

    public void run(Message a, Message b) {

        logger.info("running Application");

        logger.info(a.getMessage());

        if (a.equals(b)) {

            logger.info("The beans are the same");
        } else {

            logger.info("The beans are not the same");
        }
    }
}

This is the main application class.

var bean1 = ctx.getBean(Message.class);
var bean2 = ctx.getBean(Message.class);

app.run(bean1, bean2);

We get the two beans from the application context and pass them to the run method for comparison.

logger.info(a.getMessage());

We read the message from the bean.

if (a.equals(b)) {

    logger.info("The beans are the same");
} else {

    logger.info("The beans are not the same");
}

We test if the two beans are identical.

$ mvn -q exec:java
21:28:35.573 [com.zetcode.Application.main()] INFO  com.zetcode.Application - running Application
21:28:35.575 [com.zetcode.Application.main()] INFO  com.zetcode.Application - Application ScopeSingleton was created by Jan Bodnar
21:28:35.576 [com.zetcode.Application.main()] INFO  com.zetcode.Application - The beans are the same

We run the application. Change the scope of the Message bean to prototype and compare the results.

In this article we have worked with a Singleton Spring bean.

Author

My name is Jan Bodnar and I am a passionate programmer with many years of programming experience. I have been writing programming articles since 2007. So far, I have written over 1400 articles and 8 e-books. I have over eight years of experience in teaching programming.

List all Spring tutorials.