From b469e62c8acbfdeffce379e94ac46bcfaf29754c Mon Sep 17 00:00:00 2001 From: Artem Bilan Date: Sun, 10 Apr 2016 12:35:36 -0400 Subject: [PATCH] INT-3984: Fix the `BFPP`s order JIRA: https://jira.spring.io/browse/INT-3984 The `PropertySourcesPlaceholderConfigurer implements BeanFactoryPostProcessor, PriorityOrdered` meaning that it is run before any other regular `BeanFactoryPostProcessor`, like the `IntegrationConfigurationBeanFactoryPostProcessor` has been before. With such an order any `BeanDefinition` declaration from the `IntegrationConfigurationBeanFactoryPostProcessor` process ended up without `PP` resolutions. * Rework `IntegrationConfigurationBeanFactoryPostProcessor` to the `BeanDefinitionRegistryPostProcessor`, which makes it be loaded as early as possible. See `PostProcessorRegistrationDelegate`: ````java // Now, invoke the postProcessBeanFactory callback of all processors handled so far. invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); ```` * Modify `EnableIntegrationTests` and `ChannelSecurityInterceptorSecuredChannelAnnotationTests` to ensure that the change meets the `PP` and `SpEL` resolutions during bean definition phase. * Fix the timing issue in the `JdbcMessageStoreChannelIntegrationTests` --- ...ConfigurationBeanFactoryPostProcessor.java | 34 +++++++++---------- .../configuration/EnableIntegrationTests.java | 2 +- .../EnableIntegrationTests.properties | 1 + ...bcMessageStoreChannelIntegrationTests.java | 6 ++-- ...erceptorSecuredChannelAnnotationTests.java | 8 ++++- 5 files changed, 29 insertions(+), 22 deletions(-) diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationConfigurationBeanFactoryPostProcessor.java b/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationConfigurationBeanFactoryPostProcessor.java index 383b8e8c0e..0b8369c56d 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationConfigurationBeanFactoryPostProcessor.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/IntegrationConfigurationBeanFactoryPostProcessor.java @@ -16,15 +16,14 @@ package org.springframework.integration.config; -import java.util.HashSet; -import java.util.Set; +import java.util.List; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; import org.springframework.core.io.support.SpringFactoriesLoader; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; /** * {@link BeanFactoryPostProcessor} to apply external Integration infrastructure configurations @@ -33,24 +32,23 @@ import org.springframework.util.ClassUtils; * @author Artem Bilan * @since 4.0 */ -public class IntegrationConfigurationBeanFactoryPostProcessor implements BeanFactoryPostProcessor { +public class IntegrationConfigurationBeanFactoryPostProcessor implements BeanDefinitionRegistryPostProcessor { @Override - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { - Set initializerNames = new HashSet( - SpringFactoriesLoader.loadFactoryNames(IntegrationConfigurationInitializer.class, beanFactory.getBeanClassLoader())); + public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { + ConfigurableListableBeanFactory beanFactory = (ConfigurableListableBeanFactory) registry; - for (String initializerName : initializerNames) { - try { - Class instanceClass = ClassUtils.forName(initializerName, beanFactory.getBeanClassLoader()); - Assert.isAssignable(IntegrationConfigurationInitializer.class, instanceClass); - IntegrationConfigurationInitializer instance = (IntegrationConfigurationInitializer) instanceClass.newInstance(); - instance.initialize(beanFactory); - } - catch (Exception e) { - throw new IllegalArgumentException("Cannot instantiate 'IntegrationConfigurationInitializer': " + initializerName, e); - } + List initializers = + SpringFactoriesLoader.loadFactories(IntegrationConfigurationInitializer.class, + beanFactory.getBeanClassLoader()); + + for (IntegrationConfigurationInitializer initializer : initializers) { + initializer.initialize(beanFactory); } } + @Override + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { + } + } diff --git a/spring-integration-core/src/test/java/org/springframework/integration/configuration/EnableIntegrationTests.java b/spring-integration-core/src/test/java/org/springframework/integration/configuration/EnableIntegrationTests.java index a633ad59ca..d5cfcfa3f2 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/configuration/EnableIntegrationTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/configuration/EnableIntegrationTests.java @@ -735,7 +735,7 @@ public class EnableIntegrationTests { @Bean - @GlobalChannelInterceptor(patterns = "input") + @GlobalChannelInterceptor(patterns = "${global.wireTap.pattern}") public WireTap wireTap() { return new WireTap(this.wireTapChannel()); } diff --git a/spring-integration-core/src/test/java/org/springframework/integration/configuration/EnableIntegrationTests.properties b/spring-integration-core/src/test/java/org/springframework/integration/configuration/EnableIntegrationTests.properties index 8efc0502b5..913ab6b051 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/configuration/EnableIntegrationTests.properties +++ b/spring-integration-core/src/test/java/org/springframework/integration/configuration/EnableIntegrationTests.properties @@ -1,3 +1,4 @@ message.history.tracked.components=input, publishedChannel, annotationTestService* poller.maxMessagesPerPoll=10 poller.interval=100 +global.wireTap.pattern=input diff --git a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/JdbcMessageStoreChannelIntegrationTests.java b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/JdbcMessageStoreChannelIntegrationTests.java index d2ae0ce886..4c03033e4e 100644 --- a/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/JdbcMessageStoreChannelIntegrationTests.java +++ b/spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/JdbcMessageStoreChannelIntegrationTests.java @@ -94,7 +94,7 @@ public class JdbcMessageStoreChannelIntegrationTests { @Test public void testSendAndActivate() throws Exception { input.send(new GenericMessage("foo")); - Service.await(1000); + Service.await(10000); assertEquals(1, Service.messages.size()); } @@ -102,7 +102,7 @@ public class JdbcMessageStoreChannelIntegrationTests { public void testSendAndActivateWithRollback() throws Exception { Service.fail = true; input.send(new GenericMessage("foo")); - Service.await(1000); + Service.await(10000); assertThat(Service.messages.size(), Matchers.greaterThanOrEqualTo(1)); // After a rollback in the poller the message is still waiting to be delivered // but unless we use a transaction here there is a chance that the queue will @@ -252,6 +252,7 @@ public class JdbcMessageStoreChannelIntegrationTests { } public static class Service { + private static boolean fail = false; private static List messages = new CopyOnWriteArrayList(); @@ -278,6 +279,7 @@ public class JdbcMessageStoreChannelIntegrationTests { } return input; } + } } diff --git a/spring-integration-security/src/test/java/org/springframework/integration/security/config/ChannelSecurityInterceptorSecuredChannelAnnotationTests.java b/spring-integration-security/src/test/java/org/springframework/integration/security/config/ChannelSecurityInterceptorSecuredChannelAnnotationTests.java index 5caf9acc26..30b1dbaf06 100644 --- a/spring-integration-security/src/test/java/org/springframework/integration/security/config/ChannelSecurityInterceptorSecuredChannelAnnotationTests.java +++ b/spring-integration-security/src/test/java/org/springframework/integration/security/config/ChannelSecurityInterceptorSecuredChannelAnnotationTests.java @@ -32,6 +32,7 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.ImportResource; +import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; import org.springframework.integration.annotation.BridgeTo; import org.springframework.integration.annotation.Poller; import org.springframework.integration.channel.DirectChannel; @@ -207,6 +208,11 @@ public class ChannelSecurityInterceptorSecuredChannelAnnotationTests { @ImportResource("classpath:org/springframework/integration/security/config/commonSecurityConfiguration.xml") public static class ContextConfiguration { + @Bean + public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { + return new PropertySourcesPlaceholderConfigurer(); + } + @Bean @SecuredChannel(interceptor = "channelSecurityInterceptor", sendAccess = {"ROLE_ADMIN", "ROLE_PRESIDENT"}) public SubscribableChannel securedChannel() { @@ -225,7 +231,7 @@ public class ChannelSecurityInterceptorSecuredChannelAnnotationTests { } @Bean - @GlobalChannelInterceptor(patterns = {"queueChannel", "executorChannel"}) + @GlobalChannelInterceptor(patterns = {"#{'queueChannel'}", "${security.channel:executorChannel}"}) public ChannelInterceptor securityContextPropagationInterceptor() { return new SecurityContextPropagationChannelInterceptor(); }