diff --git a/spring-core/src/main/java/com/baeldung/scope/AppConfig.java b/spring-core/src/main/java/com/baeldung/scope/AppConfig.java new file mode 100644 index 0000000000..5c8c539e7a --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/scope/AppConfig.java @@ -0,0 +1,43 @@ +package com.baeldung.scope; + +import com.baeldung.scope.prototype.PrototypeBean; +import com.baeldung.scope.singletone.SingletonAppContextBean; +import com.baeldung.scope.singletone.SingletonBean; +import com.baeldung.scope.singletone.SingletonObjectFactoryBean; +import com.baeldung.scope.singletone.SingletonProviderBean; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Scope; + +@Configuration +@ComponentScan("com.baeldung.scope") +public class AppConfig { + + @Bean + @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) + public PrototypeBean prototypeBean() { + return new PrototypeBean(); + } + + @Bean + public SingletonBean singletonBean() { + return new SingletonBean(); + } + + @Bean + public SingletonProviderBean singletonProviderBean() { + return new SingletonProviderBean(); + } + + @Bean + public SingletonAppContextBean singletonAppContextBean() { + return new SingletonAppContextBean(); + } + + @Bean + public SingletonObjectFactoryBean singletonObjectFactoryBean() { + return new SingletonObjectFactoryBean(); + } +} diff --git a/spring-core/src/main/java/com/baeldung/scope/AppProxyScopeConfig.java b/spring-core/src/main/java/com/baeldung/scope/AppProxyScopeConfig.java new file mode 100644 index 0000000000..fc7a30471c --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/scope/AppProxyScopeConfig.java @@ -0,0 +1,22 @@ +package com.baeldung.scope; + +import com.baeldung.scope.prototype.PrototypeBean; +import com.baeldung.scope.singletone.SingletonBean; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.*; + +@Configuration +@ComponentScan("com.baeldung.scope") +public class AppProxyScopeConfig { + + @Bean + @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE, proxyMode = ScopedProxyMode.TARGET_CLASS) + public PrototypeBean prototypeBean() { + return new PrototypeBean(); + } + + @Bean + public SingletonBean singletonBean() { + return new SingletonBean(); + } +} diff --git a/spring-core/src/main/java/com/baeldung/scope/BeanInjectionStarter.java b/spring-core/src/main/java/com/baeldung/scope/BeanInjectionStarter.java new file mode 100644 index 0000000000..5cf0c9170c --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/scope/BeanInjectionStarter.java @@ -0,0 +1,22 @@ +package com.baeldung.scope; + +import com.baeldung.scope.prototype.PrototypeBean; +import com.baeldung.scope.singletone.SingletonBean; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.util.Assert; + +public class BeanInjectionStarter { + + public static void main(String[] args) throws InterruptedException { + + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); + SingletonBean firstSingleton = context.getBean(SingletonBean.class); + PrototypeBean firstPrototype = firstSingleton.getPrototypeBean(); + + SingletonBean secondSingleton = context.getBean(SingletonBean.class); + PrototypeBean secondPrototype = secondSingleton.getPrototypeBean(); + + Assert.isTrue(firstPrototype.equals(secondPrototype), "The same instance is returned"); + + } +} diff --git a/spring-core/src/main/java/com/baeldung/scope/prototype/PrototypeBean.java b/spring-core/src/main/java/com/baeldung/scope/prototype/PrototypeBean.java new file mode 100644 index 0000000000..cfccb62e45 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/scope/prototype/PrototypeBean.java @@ -0,0 +1,12 @@ +package com.baeldung.scope.prototype; + +import org.apache.log4j.Logger; + +public class PrototypeBean { + + private final Logger logger = Logger.getLogger(this.getClass()); + + public PrototypeBean() { + logger.info("Prototype instance created"); + } +} diff --git a/spring-core/src/main/java/com/baeldung/scope/singletone/SingletonAppContextBean.java b/spring-core/src/main/java/com/baeldung/scope/singletone/SingletonAppContextBean.java new file mode 100644 index 0000000000..f4d57a0f63 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/scope/singletone/SingletonAppContextBean.java @@ -0,0 +1,20 @@ +package com.baeldung.scope.singletone; + +import com.baeldung.scope.prototype.PrototypeBean; +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; + +public class SingletonAppContextBean implements ApplicationContextAware { + + private ApplicationContext applicationContext; + + public PrototypeBean getPrototypeBean() { + return applicationContext.getBean(PrototypeBean.class); + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + } +} diff --git a/spring-core/src/main/java/com/baeldung/scope/singletone/SingletonBean.java b/spring-core/src/main/java/com/baeldung/scope/singletone/SingletonBean.java new file mode 100644 index 0000000000..8d3a09b8fd --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/scope/singletone/SingletonBean.java @@ -0,0 +1,24 @@ +package com.baeldung.scope.singletone; + +import com.baeldung.scope.prototype.PrototypeBean; +import org.apache.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; + +import java.time.LocalTime; + +public class SingletonBean { + + private final Logger logger = Logger.getLogger(this.getClass()); + + @Autowired + private PrototypeBean prototypeBean; + + public SingletonBean() { + logger.info("Singleton instance created"); + } + + public PrototypeBean getPrototypeBean() { + logger.info(String.valueOf(LocalTime.now())); + return prototypeBean; + } +} diff --git a/spring-core/src/main/java/com/baeldung/scope/singletone/SingletonLookupBean.java b/spring-core/src/main/java/com/baeldung/scope/singletone/SingletonLookupBean.java new file mode 100644 index 0000000000..4c3c9b69da --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/scope/singletone/SingletonLookupBean.java @@ -0,0 +1,14 @@ +package com.baeldung.scope.singletone; + +import com.baeldung.scope.prototype.PrototypeBean; +import org.springframework.beans.factory.annotation.Lookup; +import org.springframework.stereotype.Component; + +@Component +public class SingletonLookupBean { + + @Lookup + public PrototypeBean getPrototypeBean() { + return null; + } +} diff --git a/spring-core/src/main/java/com/baeldung/scope/singletone/SingletonObjectFactoryBean.java b/spring-core/src/main/java/com/baeldung/scope/singletone/SingletonObjectFactoryBean.java new file mode 100644 index 0000000000..55a91f8202 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/scope/singletone/SingletonObjectFactoryBean.java @@ -0,0 +1,15 @@ +package com.baeldung.scope.singletone; + +import com.baeldung.scope.prototype.PrototypeBean; +import org.springframework.beans.factory.ObjectFactory; +import org.springframework.beans.factory.annotation.Autowired; + +public class SingletonObjectFactoryBean { + + @Autowired + private ObjectFactory prototypeBeanObjectFactory; + + public PrototypeBean getPrototypeInstance() { + return prototypeBeanObjectFactory.getObject(); + } +} diff --git a/spring-core/src/main/java/com/baeldung/scope/singletone/SingletonProviderBean.java b/spring-core/src/main/java/com/baeldung/scope/singletone/SingletonProviderBean.java new file mode 100644 index 0000000000..37d0ad9404 --- /dev/null +++ b/spring-core/src/main/java/com/baeldung/scope/singletone/SingletonProviderBean.java @@ -0,0 +1,16 @@ +package com.baeldung.scope.singletone; + +import com.baeldung.scope.prototype.PrototypeBean; +import org.springframework.beans.factory.annotation.Autowired; + +import javax.inject.Provider; + +public class SingletonProviderBean { + + @Autowired + private Provider myPrototypeBeanProvider; + + public PrototypeBean getPrototypeInstance() { + return myPrototypeBeanProvider.get(); + } +} diff --git a/spring-core/src/test/java/com/baeldung/scope/PrototypeBeanInjectionTest.java b/spring-core/src/test/java/com/baeldung/scope/PrototypeBeanInjectionTest.java new file mode 100644 index 0000000000..0c4c5d6069 --- /dev/null +++ b/spring-core/src/test/java/com/baeldung/scope/PrototypeBeanInjectionTest.java @@ -0,0 +1,61 @@ +package com.baeldung.scope; + +import com.baeldung.scope.prototype.PrototypeBean; +import com.baeldung.scope.singletone.SingletonLookupBean; +import com.baeldung.scope.singletone.SingletonObjectFactoryBean; +import com.baeldung.scope.singletone.SingletonProviderBean; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.support.AbstractApplicationContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.support.AnnotationConfigContextLoader; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(loader = AnnotationConfigContextLoader.class, classes = AppConfig.class) +public class PrototypeBeanInjectionTest { + + @Test + public void givenPrototypeInjection_WhenObjectFactory_ThenNewInstanceReturn() { + + AbstractApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); + + SingletonObjectFactoryBean firstContext = context.getBean(SingletonObjectFactoryBean.class); + SingletonObjectFactoryBean secondContext = context.getBean(SingletonObjectFactoryBean.class); + + PrototypeBean firstInstance = firstContext.getPrototypeInstance(); + PrototypeBean secondInstance = secondContext.getPrototypeInstance(); + + Assert.assertTrue("New instance expected", firstInstance != secondInstance); + } + + @Test + public void givenPrototypeInjection_WhenLookup_ThenNewInstanceReturn() { + + AbstractApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); + + SingletonLookupBean firstContext = context.getBean(SingletonLookupBean.class); + SingletonLookupBean secondContext = context.getBean(SingletonLookupBean.class); + + PrototypeBean firstInstance = firstContext.getPrototypeBean(); + PrototypeBean secondInstance = secondContext.getPrototypeBean(); + + Assert.assertTrue("New instance expected", firstInstance != secondInstance); + } + + @Test + public void givenPrototypeInjection_WhenProvider_ThenNewInstanceReturn() { + + AbstractApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); + + SingletonProviderBean firstContext = context.getBean(SingletonProviderBean.class); + SingletonProviderBean secondContext = context.getBean(SingletonProviderBean.class); + + PrototypeBean firstInstance = firstContext.getPrototypeInstance(); + PrototypeBean secondInstance = secondContext.getPrototypeInstance(); + + Assert.assertTrue("New instance expected", firstInstance != secondInstance); + } +}