diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/dsl/IntegrationFlowBeanPostProcessor.java b/spring-integration-core/src/main/java/org/springframework/integration/config/dsl/IntegrationFlowBeanPostProcessor.java index 44b3d8d205..b121058c76 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/dsl/IntegrationFlowBeanPostProcessor.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/dsl/IntegrationFlowBeanPostProcessor.java @@ -21,18 +21,30 @@ import java.util.LinkedHashMap; import java.util.Map; import org.springframework.beans.BeansException; +import org.springframework.beans.factory.Aware; +import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.BeanCreationNotAllowedException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.BeanFactoryUtils; +import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.SmartInitializingSingleton; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinitionCustomizer; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.beans.factory.config.EmbeddedValueResolver; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.BeanDefinitionRegistry; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.context.ApplicationEventPublisherAware; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.EmbeddedValueResolverAware; +import org.springframework.context.EnvironmentAware; +import org.springframework.context.MessageSourceAware; +import org.springframework.context.ResourceLoaderAware; import org.springframework.core.io.DescriptiveResource; import org.springframework.integration.channel.AbstractMessageChannel; import org.springframework.integration.channel.DirectChannel; @@ -57,6 +69,7 @@ import org.springframework.messaging.MessageHandler; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; +import org.springframework.util.StringValueResolver; /** * A {@link BeanPostProcessor} to parse {@link IntegrationFlow} beans and @@ -69,20 +82,26 @@ import org.springframework.util.StringUtils; * @since 5.0 */ public class IntegrationFlowBeanPostProcessor - implements BeanPostProcessor, BeanFactoryAware, SmartInitializingSingleton { + implements BeanPostProcessor, ApplicationContextAware, SmartInitializingSingleton { + + private ConfigurableApplicationContext applicationContext; + + private StringValueResolver embeddedValueResolver; private ConfigurableListableBeanFactory beanFactory; private IntegrationFlowContext flowContext; @Override - public void setBeanFactory(BeanFactory beanFactory) throws BeansException { - Assert.isInstanceOf(ConfigurableListableBeanFactory.class, beanFactory, - "To use Spring Integration Java DSL the 'beanFactory' has to be an instance of " + - "'ConfigurableListableBeanFactory'. Consider using 'GenericApplicationContext' implementation." + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + Assert.isInstanceOf(ConfigurableApplicationContext.class, applicationContext, + "To use Spring Integration Java DSL the 'applicationContext' has to be an instance of " + + "'ConfigurableApplicationContext'. Consider using 'GenericApplicationContext' implementation." ); - this.beanFactory = (ConfigurableListableBeanFactory) beanFactory; + this.applicationContext = (ConfigurableApplicationContext) applicationContext; + this.beanFactory = this.applicationContext.getBeanFactory(); + this.embeddedValueResolver = new EmbeddedValueResolver(this.beanFactory); this.flowContext = this.beanFactory.getBean(IntegrationFlowContext.class); Assert.notNull(this.flowContext, "There must be an IntegrationFlowContext in the application context"); } @@ -96,7 +115,7 @@ public class IntegrationFlowBeanPostProcessor return processIntegrationFlowImpl((IntegrationFlow) bean, beanName); } if (bean instanceof IntegrationComponentSpec) { - processIntegrationComponentSpec((IntegrationComponentSpec) bean); + processIntegrationComponentSpec(beanName, (IntegrationComponentSpec) bean); } return bean; } @@ -280,7 +299,11 @@ public class IntegrationFlowBeanPostProcessor return isLambda(flow) ? standardIntegrationFlow : flow; } - private void processIntegrationComponentSpec(IntegrationComponentSpec bean) { + private void processIntegrationComponentSpec(String beanName, IntegrationComponentSpec bean) { + Object target = bean.get(); + + invokeBeanInitializationHooks(beanName, target); + if (bean instanceof ComponentsRegistration) { Map componentsToRegister = ((ComponentsRegistration) bean).getComponentsToRegister(); if (!CollectionUtils.isEmpty(componentsToRegister)) { @@ -299,6 +322,38 @@ public class IntegrationFlowBeanPostProcessor } } + private void invokeBeanInitializationHooks(final String beanName, final Object bean) { + if (bean instanceof Aware) { + if (bean instanceof BeanNameAware) { + ((BeanNameAware) bean).setBeanName(beanName); + } + if (bean instanceof BeanClassLoaderAware) { + ((BeanClassLoaderAware) bean).setBeanClassLoader(this.beanFactory.getBeanClassLoader()); + } + if (bean instanceof BeanFactoryAware) { + ((BeanFactoryAware) bean).setBeanFactory(this.beanFactory); + } + if (bean instanceof EnvironmentAware) { + ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment()); + } + if (bean instanceof EmbeddedValueResolverAware) { + ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver); + } + if (bean instanceof ResourceLoaderAware) { + ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext); + } + if (bean instanceof ApplicationEventPublisherAware) { + ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext); + } + if (bean instanceof MessageSourceAware) { + ((MessageSourceAware) bean).setMessageSource(this.applicationContext); + } + if (bean instanceof ApplicationContextAware) { + ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext); + } + } + } + private void registerComponent(Object component, String beanName) { registerComponent(component, beanName, null); } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/dsl/IntegrationComponentSpec.java b/spring-integration-core/src/main/java/org/springframework/integration/dsl/IntegrationComponentSpec.java index b8144c1a74..71bd0f8533 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/dsl/IntegrationComponentSpec.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/dsl/IntegrationComponentSpec.java @@ -1,5 +1,5 @@ /* - * Copyright 2016 the original author or authors. + * Copyright 2016-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,9 @@ package org.springframework.integration.dsl; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.FactoryBean; +import org.springframework.beans.factory.InitializingBean; import org.springframework.expression.spel.standard.SpelExpressionParser; /** @@ -33,7 +35,7 @@ import org.springframework.expression.spel.standard.SpelExpressionParser; * @since 5.0 */ public abstract class IntegrationComponentSpec, T> - implements FactoryBean { + implements FactoryBean, InitializingBean, DisposableBean { protected final static SpelExpressionParser PARSER = new SpelExpressionParser(); @@ -83,6 +85,20 @@ public abstract class IntegrationComponentSpec testSpec() { + return new MyIntegrationComponentSpec(); + } + + } + + private static final class MyIntegrationComponentSpec + extends IntegrationComponentSpec { + + MyIntegrationComponentSpec() { + this.target = new MyComponent(); + } + + } + + private static final class MyComponent + implements InitializingBean, BeanNameAware, BeanFactoryAware, ApplicationContextAware, + BeanClassLoaderAware, EnvironmentAware, EmbeddedValueResolverAware, ResourceLoaderAware, + ApplicationEventPublisherAware, MessageSourceAware { + + private boolean initialized; + + private ClassLoader classLoader; + + private BeanFactory beanFactory; + + private String name; + + private ApplicationContext applicationContext; + + private ApplicationEventPublisher applicationEventPublisher; + + private StringValueResolver resolver; + + private Environment environment; + + private MessageSource messageSource; + + private ResourceLoader resourceLoader; + + @Override + public void setBeanClassLoader(ClassLoader classLoader) { + this.classLoader = classLoader; + } + + @Override + public void setBeanFactory(BeanFactory beanFactory) throws BeansException { + this.beanFactory = beanFactory; + } + + @Override + public void setBeanName(String name) { + this.name = name; + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + this.applicationContext = applicationContext; + } + + @Override + public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { + this.applicationEventPublisher = applicationEventPublisher; + } + + @Override + public void setEmbeddedValueResolver(StringValueResolver resolver) { + this.resolver = resolver; + } + + @Override + public void setEnvironment(Environment environment) { + this.environment = environment; + } + + @Override + public void setMessageSource(MessageSource messageSource) { + this.messageSource = messageSource; + } + + @Override + public void setResourceLoader(ResourceLoader resourceLoader) { + this.resourceLoader = resourceLoader; + } + + @Override + public void afterPropertiesSet() { + this.initialized = true; + } + + } + +}