diff --git a/spring-boot-modules/spring-boot-3/src/main/java/com/baeldung/sample/singleton/SingletonBeanConfig.java b/spring-boot-modules/spring-boot-3/src/main/java/com/baeldung/sample/singleton/SingletonBeanConfig.java new file mode 100644 index 0000000000..1c40097ba5 --- /dev/null +++ b/spring-boot-modules/spring-boot-3/src/main/java/com/baeldung/sample/singleton/SingletonBeanConfig.java @@ -0,0 +1,29 @@ +package com.baeldung.sample.singleton; + +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Scope; + +@Configuration +public class SingletonBeanConfig { + + @Bean + @Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON) + public SingletonBean singletonBean() { + return new SingletonBean(); + } + + @Bean + @Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON) + public SingletonBean anotherSingletonBean() { + return new SingletonBean(); + } + + static class SingletonBean { + public String getValue() { + return "test"; + } + } + +} diff --git a/spring-boot-modules/spring-boot-3/src/main/java/com/baeldung/sample/singleton/ThreadSafeSingleInstance.java b/spring-boot-modules/spring-boot-3/src/main/java/com/baeldung/sample/singleton/ThreadSafeSingleInstance.java new file mode 100644 index 0000000000..ae6e85bf2b --- /dev/null +++ b/spring-boot-modules/spring-boot-3/src/main/java/com/baeldung/sample/singleton/ThreadSafeSingleInstance.java @@ -0,0 +1,24 @@ +package com.baeldung.sample.singleton; + +public final class ThreadSafeSingleInstance { + + private static volatile ThreadSafeSingleInstance instance = null; + + private ThreadSafeSingleInstance() {} + + public static ThreadSafeSingleInstance getInstance() { + if (instance == null) { + synchronized(ThreadSafeSingleInstance.class) { + if (instance == null) { + instance = new ThreadSafeSingleInstance(); + } + } + } + return instance; + } + + public String getValue() { + return "test"; + } + +} diff --git a/spring-boot-modules/spring-boot-3/src/test/java/com/baeldung/sample/singleton/SingletonBeanUnitTest.java b/spring-boot-modules/spring-boot-3/src/test/java/com/baeldung/sample/singleton/SingletonBeanUnitTest.java new file mode 100644 index 0000000000..72c1ae4170 --- /dev/null +++ b/spring-boot-modules/spring-boot-3/src/test/java/com/baeldung/sample/singleton/SingletonBeanUnitTest.java @@ -0,0 +1,35 @@ +package com.baeldung.sample.singleton; + +import static org.junit.jupiter.api.Assertions.assertNotSame; +import static org.junit.jupiter.api.Assertions.assertSame; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class SingletonBeanUnitTest { + + @Autowired + @Qualifier("singletonBean") + private SingletonBeanConfig.SingletonBean beanOne; + + @Autowired + @Qualifier("singletonBean") + private SingletonBeanConfig.SingletonBean beanTwo; + + @Autowired + @Qualifier("anotherSingletonBean") + private SingletonBeanConfig.SingletonBean beanThree; + + @Test + void givenTwoBeansWithSameId_whenInjectingThem_thenSameInstancesAreReturned() { + assertSame(beanOne, beanTwo); + } + + @Test + void givenTwoBeansWithDifferentId_whenInjectingThem_thenDifferentInstancesAreReturned() { + assertNotSame(beanOne, beanThree); + } + +} diff --git a/spring-boot-modules/spring-boot-3/src/test/java/com/baeldung/sample/singleton/ThreadSafeSingleInstanceUnitTest.java b/spring-boot-modules/spring-boot-3/src/test/java/com/baeldung/sample/singleton/ThreadSafeSingleInstanceUnitTest.java new file mode 100644 index 0000000000..0753f92e31 --- /dev/null +++ b/spring-boot-modules/spring-boot-3/src/test/java/com/baeldung/sample/singleton/ThreadSafeSingleInstanceUnitTest.java @@ -0,0 +1,16 @@ +package com.baeldung.sample.singleton; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertSame; + +class ThreadSafeSingleInstanceUnitTest { + + @Test + void givenTwoSingletonInstances_whenGettingThem_thenSameInstancesAreReturned() { + ThreadSafeSingleInstance instanceOne = ThreadSafeSingleInstance.getInstance(); + ThreadSafeSingleInstance instanceTwo = ThreadSafeSingleInstance.getInstance(); + assertSame(instanceOne, instanceTwo); + } + +}