From b18330972884e8cb6832b0bdbd6c9f545dc1f501 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Tue, 10 Feb 2015 20:14:38 +0000 Subject: [PATCH] Stop a BeanPostProcessor from preventing config of packages to scan MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, if a BeanPostProcessor bean was declared in a configuration class that depended on the persistence context, packages to scan would not be configured on the LocalContainerEntityManagerFactoryBean. This was due to the BeanPostProcessor bean triggering the early instantiation of the LCEMFB before EntityScanBeanPostProcessor, the BeanPostProcessor, that applies the @EntityScan configuration, had been given a chance to configure it. This commit updates EntityScanBeanPostProcessor to implement Ordered with an order of zero. This ensures that its ordering is predictable and that it will be driven before any unordered BeanPostProcessor. This means that, unless the user has specifically ordered their BeanPostProcessor to run before EntityScanBeanPostProcessor, LCEMFB’s packages to scan will be configured as expected. Fixes gh-2478 --- .../boot/orm/jpa/EntityScanRegistrar.java | 8 +++- .../boot/orm/jpa/EntityScanTests.java | 37 +++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/spring-boot/src/main/java/org/springframework/boot/orm/jpa/EntityScanRegistrar.java b/spring-boot/src/main/java/org/springframework/boot/orm/jpa/EntityScanRegistrar.java index 36edab5e0c..48d8d51651 100644 --- a/spring-boot/src/main/java/org/springframework/boot/orm/jpa/EntityScanRegistrar.java +++ b/spring-boot/src/main/java/org/springframework/boot/orm/jpa/EntityScanRegistrar.java @@ -28,6 +28,7 @@ import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.GenericBeanDefinition; import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; +import org.springframework.core.Ordered; import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.type.AnnotationMetadata; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; @@ -91,7 +92,7 @@ class EntityScanRegistrar implements ImportBeanDefinitionRegistrar { * on an {@link EntityScan} annotation. */ static class EntityScanBeanPostProcessor implements BeanPostProcessor, - SmartInitializingSingleton { + SmartInitializingSingleton, Ordered { private final String[] packagesToScan; @@ -125,6 +126,11 @@ class EntityScanRegistrar implements ImportBeanDefinitionRegistrar { + "ensure an appropriate bean is registered."); } + @Override + public int getOrder() { + return 0; + } + } } diff --git a/spring-boot/src/test/java/org/springframework/boot/orm/jpa/EntityScanTests.java b/spring-boot/src/test/java/org/springframework/boot/orm/jpa/EntityScanTests.java index 82334eb9c5..5461c9e2fb 100644 --- a/spring-boot/src/test/java/org/springframework/boot/orm/jpa/EntityScanTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/orm/jpa/EntityScanTests.java @@ -22,6 +22,9 @@ import javax.persistence.PersistenceException; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -99,6 +102,13 @@ public class EntityScanTests { this.context = new AnnotationConfigApplicationContext(MissingEntityManager.class); } + @Test + public void userDeclaredBeanPostProcessorWithEntityManagerDependencyDoesNotPreventConfigurationOfPackagesToScan() { + this.context = new AnnotationConfigApplicationContext( + BeanPostProcessorConfiguration.class, BaseConfig.class); + assertSetPackagesToScan("com.mycorp.entity"); + } + private void assertSetPackagesToScan(String... expected) { String[] actual = this.context.getBean( TestLocalContainerEntityManagerFactoryBean.class).getPackagesToScan(); @@ -148,6 +158,33 @@ public class EntityScanTests { static class MissingEntityManager { } + @Configuration + @EntityScan("com.mycorp.entity") + static class BeanPostProcessorConfiguration { + + @Autowired + private EntityManagerFactory entityManagerFactory; + + @Bean + public BeanPostProcessor beanPostProcessor() { + return new BeanPostProcessor() { + + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) + throws BeansException { + return bean; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) + throws BeansException { + return bean; + } + }; + + } + } + private static class TestLocalContainerEntityManagerFactoryBean extends LocalContainerEntityManagerFactoryBean {