INT-3984: Fix the BFPPs 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`
This commit is contained in:
committed by
Gary Russell
parent
1df7815148
commit
b469e62c8a
@@ -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<String> initializerNames = new HashSet<String>(
|
||||
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<IntegrationConfigurationInitializer> initializers =
|
||||
SpringFactoriesLoader.loadFactories(IntegrationConfigurationInitializer.class,
|
||||
beanFactory.getBeanClassLoader());
|
||||
|
||||
for (IntegrationConfigurationInitializer initializer : initializers) {
|
||||
initializer.initialize(beanFactory);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -735,7 +735,7 @@ public class EnableIntegrationTests {
|
||||
|
||||
|
||||
@Bean
|
||||
@GlobalChannelInterceptor(patterns = "input")
|
||||
@GlobalChannelInterceptor(patterns = "${global.wireTap.pattern}")
|
||||
public WireTap wireTap() {
|
||||
return new WireTap(this.wireTapChannel());
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
message.history.tracked.components=input, publishedChannel, annotationTestService*
|
||||
poller.maxMessagesPerPoll=10
|
||||
poller.interval=100
|
||||
global.wireTap.pattern=input
|
||||
|
||||
@@ -94,7 +94,7 @@ public class JdbcMessageStoreChannelIntegrationTests {
|
||||
@Test
|
||||
public void testSendAndActivate() throws Exception {
|
||||
input.send(new GenericMessage<String>("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<String>("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<String> messages = new CopyOnWriteArrayList<String>();
|
||||
@@ -278,6 +279,7 @@ public class JdbcMessageStoreChannelIntegrationTests {
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user