From eb0f2829cc19d7f56245907819ee4a70d25c64dd Mon Sep 17 00:00:00 2001 From: mperor Date: Sun, 29 Jun 2025 15:55:47 +0200 Subject: [PATCH] Separated concerns: scope verification vs. bean ordering in Spring --- .../lab/spring/config/OrderableBeans.java | 39 +++++++++++++++ .../{Beans.java => config/ScopedBeans.java} | 37 +------------- .../spring/SpringCoreLabApplicationTest.java | 32 ------------ .../spring/config/SpringBeansConfigTest.java | 50 +++++++++++++++++++ 4 files changed, 91 insertions(+), 67 deletions(-) create mode 100644 spring-core-lab/src/main/java/pl/mperor/lab/spring/config/OrderableBeans.java rename spring-core-lab/src/main/java/pl/mperor/lab/spring/{Beans.java => config/ScopedBeans.java} (65%) create mode 100644 spring-core-lab/src/test/java/pl/mperor/lab/spring/config/SpringBeansConfigTest.java diff --git a/spring-core-lab/src/main/java/pl/mperor/lab/spring/config/OrderableBeans.java b/spring-core-lab/src/main/java/pl/mperor/lab/spring/config/OrderableBeans.java new file mode 100644 index 0000000..885a0ae --- /dev/null +++ b/spring-core-lab/src/main/java/pl/mperor/lab/spring/config/OrderableBeans.java @@ -0,0 +1,39 @@ +package pl.mperor.lab.spring.config; + +import org.springframework.beans.factory.BeanNameAware; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; + +@Configuration +public class OrderableBeans { + @Bean + Orderable defaultPlusPriorityOrder() { + return new Orderable(); + } + + @Bean + @Order(0) + Orderable zeroPriorityOrder() { + return new Orderable(); + } + + @Bean + @Order(Integer.MIN_VALUE) + Orderable minusPriorityOrder() { + return new Orderable(); + } + + static class Orderable implements BeanNameAware { + String beanName; + + @Override + public void setBeanName(String name) { + this.beanName = name; + } + + String getBeanName() { + return beanName; + } + } +} diff --git a/spring-core-lab/src/main/java/pl/mperor/lab/spring/Beans.java b/spring-core-lab/src/main/java/pl/mperor/lab/spring/config/ScopedBeans.java similarity index 65% rename from spring-core-lab/src/main/java/pl/mperor/lab/spring/Beans.java rename to spring-core-lab/src/main/java/pl/mperor/lab/spring/config/ScopedBeans.java index 62d0d2a..4cdb645 100644 --- a/spring-core-lab/src/main/java/pl/mperor/lab/spring/Beans.java +++ b/spring-core-lab/src/main/java/pl/mperor/lab/spring/config/ScopedBeans.java @@ -1,19 +1,17 @@ -package pl.mperor.lab.spring; +package pl.mperor.lab.spring.config; import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.config.BeanPostProcessor; 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; -import org.springframework.core.annotation.Order; import java.util.ArrayList; import java.util.List; @Configuration -public class Beans { +public class ScopedBeans { record Singleton() { } @@ -32,37 +30,6 @@ Prototype prototype() { return new Prototype(); } - static class Orderable implements BeanNameAware { - String beanName; - - @Override - public void setBeanName(String name) { - this.beanName = name; - } - - String getBeanName() { - return beanName; - } - } - - @Bean - @Order - Orderable plusPriorityOrder() { - return new Orderable(); - } - - @Bean - @Order(0) - Orderable zeroPriorityOrder() { - return new Orderable(); - } - - @Bean - @Order(Integer.MIN_VALUE) - Orderable minusPriorityOrder() { - return new Orderable(); - } - @Bean static BeanInstantiationTracker tracker() { return new BeanInstantiationTracker(); diff --git a/spring-core-lab/src/test/java/pl/mperor/lab/spring/SpringCoreLabApplicationTest.java b/spring-core-lab/src/test/java/pl/mperor/lab/spring/SpringCoreLabApplicationTest.java index 153a47d..be365fa 100644 --- a/spring-core-lab/src/test/java/pl/mperor/lab/spring/SpringCoreLabApplicationTest.java +++ b/spring-core-lab/src/test/java/pl/mperor/lab/spring/SpringCoreLabApplicationTest.java @@ -1,44 +1,12 @@ package pl.mperor.lab.spring; import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.ApplicationContext; - -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest public class SpringCoreLabApplicationTest { - @Autowired - private ApplicationContext context; - @Autowired - private Beans.BeanInstantiationTracker tracker; - @Autowired - private List orderables; - @Test public void contextLoads() { } - - @Test - public void shouldInitializeSingletonAndPrototypeScopesCorrectly() { - assertThat(context.containsBean("singleton")).isTrue(); - assertThat(context.containsBean("prototype")).isTrue(); - - assertThat(tracker.containsInitialized("singleton")).isTrue(); - assertThat(tracker.containsInitialized("prototype")).isFalse(); - - assertThat(context.getBean(Beans.Singleton.class)).isSameAs(context.getBean(Beans.Singleton.class)); - assertThat(context.getBean(Beans.Prototype.class)).isNotSameAs(context.getBean(Beans.Prototype.class)); - } - - @Test - public void shouldOrderBeansByPriority() { - assertThat(orderables) - .extracting(Beans.Orderable::getBeanName) - .containsExactly("minusPriorityOrder", "zeroPriorityOrder", "plusPriorityOrder"); - } } \ No newline at end of file diff --git a/spring-core-lab/src/test/java/pl/mperor/lab/spring/config/SpringBeansConfigTest.java b/spring-core-lab/src/test/java/pl/mperor/lab/spring/config/SpringBeansConfigTest.java new file mode 100644 index 0000000..1f4d835 --- /dev/null +++ b/spring-core-lab/src/test/java/pl/mperor/lab/spring/config/SpringBeansConfigTest.java @@ -0,0 +1,50 @@ +package pl.mperor.lab.spring.config; + +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; +import org.springframework.context.ApplicationContext; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest +public class SpringBeansConfigTest { + + @Autowired + private ApplicationContext context; + @Autowired + private ScopedBeans.BeanInstantiationTracker tracker; + + @Qualifier("defaultPlusPriorityOrder") + @Autowired + private OrderableBeans.Orderable defaultOrder; + @Autowired + private List orderables; + + @Test + public void shouldInitializeSingletonAndPrototypeScopesCorrectly() { + assertThat(context.containsBean("singleton")).isTrue(); + assertThat(context.containsBean("prototype")).isTrue(); + + assertThat(tracker.containsInitialized("singleton")).isTrue(); + assertThat(tracker.containsInitialized("prototype")).isFalse(); + + assertThat(context.getBean(ScopedBeans.Singleton.class)).isSameAs(context.getBean(ScopedBeans.Singleton.class)); + assertThat(context.getBean(ScopedBeans.Prototype.class)).isNotSameAs(context.getBean(ScopedBeans.Prototype.class)); + } + + @Test + public void shouldOrderBeansByPriority() { + assertThat(defaultOrder) + .extracting(OrderableBeans.Orderable::getBeanName) + .isEqualTo("defaultPlusPriorityOrder"); + + assertThat(orderables) + .extracting(OrderableBeans.Orderable::getBeanName) + .containsExactly("minusPriorityOrder", "zeroPriorityOrder", "defaultPlusPriorityOrder"); + } + +}