Permalink
Browse files

INT-2434-v3 polished based on @garyrussell last comments

  • Loading branch information...
1 parent 6e34aaa commit 282edb33bae94470124aca74563ccb9a614b8094 Oleg Zhurakousky committed Mar 30, 2012
@@ -16,13 +16,13 @@
package org.springframework.integration.config.xml;
-import java.util.HashSet;
+import java.util.Collection;
import java.util.List;
-import java.util.Set;
import org.w3c.dom.Element;
import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
@@ -93,14 +93,12 @@ protected final AbstractBeanDefinition parseInternal(Element element, ParserCont
if (!parserContext.getRegistry().containsBeanDefinition(inputChannelName)){
BeanDefinition channelRegistry = parserContext.getRegistry().getBeanDefinition(ChannelInitializer.AUTO_CREATE_CHANNEL_CANDIDATES_BEAN_NAME);
-
- @SuppressWarnings("unchecked")
- Set<String> channelNames = (Set<String>) channelRegistry.getAttribute(ChannelInitializer.CHANNEL_NAMES_ATTR);
- if (channelNames == null){
- channelNames = (Set<String>) new HashSet<String>();
- channelRegistry.setAttribute(ChannelInitializer.CHANNEL_NAMES_ATTR, channelNames);
+ ConstructorArgumentValues caValues = channelRegistry.getConstructorArgumentValues();
+ if (caValues != null){
@garyrussell
garyrussell Mar 30, 2012

Should never happen, but I wonder if we should log rather than just silently ignore?

@olegz
olegz Mar 30, 2012 owner

well giving the fact that "should never happen" i say throw exception instead of log. I mean if somehow its null this would be a major mishap, dont you think?

@garyrussell
garyrussell Mar 30, 2012

Exception? or parserContext.getReaderContext().error(...) ??

A log would just say 'auto channel creation disabled', but I think an error is better.

@olegz
olegz via email Mar 30, 2012 owner
@olegz
olegz via email Mar 30, 2012 owner
+ @SuppressWarnings("unchecked")
+ Collection<String> channelCandidateNames = (Collection<String>) caValues.getArgumentValue(0, Collection.class).getValue();
+ channelCandidateNames.add(inputChannelName);
}
- channelNames.add(inputChannelName);
}
builder.addPropertyValue("inputChannelName", inputChannelName);
@@ -22,9 +22,9 @@
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
-import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
+import org.springframework.beans.factory.support.ManagedSet;
import org.springframework.beans.factory.xml.BeanDefinitionDecorator;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.NamespaceHandler;
@@ -68,19 +68,17 @@ public final BeanDefinitionHolder decorate(Node source, BeanDefinitionHolder def
}
/*
- * This method will auto-register ChannelInitializer which could also be overridden by the user
- * by simply registering a ChannelInitializer <bean> with 'autoCreate' property set to false.
- * It will also register ChannelInitializer$AutoCreateCandidatesCollector which simply collects channelNames to be created.
- * It does a little more so please read its comments. ChannelInitializer$AutoCreateCandidatesCollector
- * can NOT be overridden by the user
+ * This method will auto-register a ChannelInitializer which could also be overridden by the user
+ * by simply registering a ChannelInitializer <bean> with its 'autoCreate' property set to false to suppress channel creation.
+ * It will also register a ChannelInitializer$AutoCreateCandidatesCollector which simply collects candidate channel names.
*/
private void registerImplicitChannelCreator(ParserContext parserContext) {
// ChannelInitializer
boolean alreadyRegistered = false;
- if (parserContext.getRegistry() instanceof ConfigurableListableBeanFactory) {
+ if (parserContext.getRegistry() instanceof ListableBeanFactory) {
// unlike DefaultConfiguringBeanFactoryPostProcessor we need one of these per registry
// therefore we need to call containsBeanDefinition(..) which does not consider parent registry
- alreadyRegistered = ((ConfigurableListableBeanFactory) parserContext.getRegistry()).containsBeanDefinition(CHANNEL_INITIALIZER_BEAN_NAME);
+ alreadyRegistered = ((ListableBeanFactory) parserContext.getRegistry()).containsBeanDefinition(CHANNEL_INITIALIZER_BEAN_NAME);
}
else {
alreadyRegistered = parserContext.getRegistry().isBeanNameInUse(CHANNEL_INITIALIZER_BEAN_NAME);
@@ -92,17 +90,18 @@ private void registerImplicitChannelCreator(ParserContext parserContext) {
}
// ChannelInitializer$AutoCreateCandidatesCollector
alreadyRegistered = false;
- if (parserContext.getRegistry() instanceof ConfigurableListableBeanFactory) {
+ if (parserContext.getRegistry() instanceof ListableBeanFactory) {
// unlike DefaultConfiguringBeanFactoryPostProcessor we need one of these per registry
// therefore we need to call containsBeanDefinition(..) which does not consider parent registry
- alreadyRegistered = ((ConfigurableListableBeanFactory) parserContext.getRegistry()).
+ alreadyRegistered = ((ListableBeanFactory) parserContext.getRegistry()).
containsBeanDefinition(ChannelInitializer.AUTO_CREATE_CHANNEL_CANDIDATES_BEAN_NAME);
}
else {
alreadyRegistered = parserContext.getRegistry().isBeanNameInUse(ChannelInitializer.AUTO_CREATE_CHANNEL_CANDIDATES_BEAN_NAME);
}
if (!alreadyRegistered) {
BeanDefinitionBuilder channelRegistryBuilder = BeanDefinitionBuilder.genericBeanDefinition(AutoCreateCandidatesCollector.class);
+ channelRegistryBuilder.addConstructorArgValue(new ManagedSet<String>());
BeanDefinitionHolder channelRegistryHolder =
new BeanDefinitionHolder(channelRegistryBuilder.getBeanDefinition(), ChannelInitializer.AUTO_CREATE_CHANNEL_CANDIDATES_BEAN_NAME);
BeanDefinitionReaderUtils.registerBeanDefinition(channelRegistryHolder, parserContext.getRegistry());
@@ -24,20 +24,15 @@
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.InitializingBean;
-import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
-import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
-import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
-import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-import org.springframework.beans.factory.support.ManagedSet;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.integration.channel.DirectChannel;
/**
* A {@link InitializingBean} implementation that is responsible for creating
- * channels that are not explicitly defined but identified via 'input-channel'
+ * channels that are not explicitly defined but identified via the 'input-channel'
* attribute of the corresponding endpoints.
*
* This bean plays a role of pre-instantiator since it is instantiated and
@@ -90,44 +85,20 @@ public void afterPropertiesSet() throws Exception {
}
}
}
-
+
/*
- * This class serves two purposes
- * 1. A BeanDefinition that collects candidate channel names as its BeanDefinition attributes
- * 2. A holder of the resolved (property placeholders and SpEL expressions) channel names to be auto-created by the
- * ChannelInitializer.
- * Once this bean reaches Factory post processing phase it creates a new definition of itself injecting it with
- * the ManagedSet of channelNames property. The ManagedSet will be naturally resolved before it is used by the
- * ChannelInitializer. It also unregisters its old definition (since its only value was to provide a place
- * to collect candidate channel names) and registers new definition of itself with "to-be resolved" channelNames
- * property
+ * Collects candidate channel names to be auto-created by ChannelInitializer
*/
- public static class AutoCreateCandidatesCollector implements BeanFactoryPostProcessor{
-
- private volatile Collection<String> channelNames;
-
- public void setChannelNames(Collection<String> channelNames) {
+ static class AutoCreateCandidatesCollector {
+
+ private final Collection<String> channelNames;
+
+ public AutoCreateCandidatesCollector(Collection<String> channelNames){
this.channelNames = channelNames;
}
public Collection<String> getChannelNames() {
return channelNames;
}
-
- @SuppressWarnings("unchecked")
- public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
- BeanDefinition definition = beanFactory.getBeanDefinition(ChannelInitializer.AUTO_CREATE_CHANNEL_CANDIDATES_BEAN_NAME);
- Collection<String> _channelNames = (Collection<String>) definition.getAttribute(ChannelInitializer.CHANNEL_NAMES_ATTR);
- if (_channelNames != null){
- ((BeanDefinitionRegistry)beanFactory).removeBeanDefinition(ChannelInitializer.AUTO_CREATE_CHANNEL_CANDIDATES_BEAN_NAME);
- BeanDefinitionBuilder candidatesBuilder = BeanDefinitionBuilder.genericBeanDefinition(this.getClass().getName());
- ManagedSet<String> candidateChannelNamesToBeResolved = new ManagedSet<String>();
- candidateChannelNamesToBeResolved.addAll(_channelNames);
- candidatesBuilder.addPropertyValue("channelNames", candidateChannelNamesToBeResolved);
- BeanDefinitionHolder holder = new BeanDefinitionHolder(candidatesBuilder.getBeanDefinition(),
- ChannelInitializer.AUTO_CREATE_CHANNEL_CANDIDATES_BEAN_NAME);
- BeanDefinitionReaderUtils.registerBeanDefinition(holder, (BeanDefinitionRegistry) beanFactory);
- }
- }
}
}

0 comments on commit 282edb3

Please sign in to comment.