The <message-bus/> element is no longer necessary. It has been removed from the XSD (INT-462). The annotations are enabled by a separate element, and the application-event-multicaster element is also now separate.

This commit is contained in:
Mark Fisher
2008-11-11 23:08:45 +00:00
parent f4ccde6257
commit fea222b37f
85 changed files with 275 additions and 402 deletions

View File

@@ -87,7 +87,6 @@ public abstract class AbstractConsumerEndpointParser extends AbstractSingleBeanD
@Override
protected final void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
IntegrationNamespaceUtils.registerTaskSchedulerIfNecessary(parserContext.getRegistry());
BeanDefinitionBuilder consumerBuilder = this.parseConsumer(element, parserContext);
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(consumerBuilder, element, OUTPUT_CHANNEL_ATTRIBUTE);
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(consumerBuilder, element, SELECTOR_ATTRIBUTE);

View File

@@ -0,0 +1,66 @@
/*
* Copyright 2002-2008 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.config.xml;
import java.util.concurrent.CopyOnWriteArraySet;
import org.w3c.dom.Element;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.context.event.SimpleApplicationEventMulticaster;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.core.task.TaskExecutor;
import org.springframework.integration.context.IntegrationContextUtils;
import org.springframework.util.StringUtils;
/**
* Parser for the &lt;application-event-multicaster&gt; element of the
* integration namespace.
*
* @author Mark Fisher
*/
public class ApplicationEventMulticasterParser extends AbstractSingleBeanDefinitionParser {
@Override
protected Class<?> getBeanClass(Element element) {
return SimpleApplicationEventMulticaster.class;
}
@Override
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
throws BeanDefinitionStoreException {
return AbstractApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME;
}
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
String taskExecutorRef = element.getAttribute("task-executor");
if (StringUtils.hasText(taskExecutorRef)) {
builder.addPropertyReference("taskExecutor", taskExecutorRef);
}
else {
TaskExecutor taskExecutor = IntegrationContextUtils.createTaskExecutor(1, 10, 0, "event-multicaster-");
builder.addPropertyValue("taskExecutor", taskExecutor);
}
builder.addPropertyValue("collectionClass", CopyOnWriteArraySet.class);
}
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2002-2008 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.config.xml;
import org.w3c.dom.Element;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.annotation.MessagingAnnotationPostProcessor;
/**
* Parser for the &lt;enable-annotations&gt; element of the integration namespace.
* Adds a {@link MessagingAnnotationPostProcessor} to the application context.
*
* @author Mark Fisher
*/
public class EnableAnnotationsParser extends AbstractSingleBeanDefinitionParser {
@Override
protected Class<?> getBeanClass(Element element) {
return MessagingAnnotationPostProcessor.class;
}
@Override
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
throws BeanDefinitionStoreException {
return "internal." + MessagingAnnotationPostProcessor.class.getName();
}
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
builder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
}
}

View File

@@ -16,7 +16,23 @@
package org.springframework.integration.config.xml;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
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.RootBeanDefinition;
import org.springframework.beans.factory.xml.NamespaceHandler;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.core.task.TaskExecutor;
import org.springframework.integration.channel.MessagePublishingErrorHandler;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.context.IntegrationContextUtils;
import org.springframework.integration.scheduling.SimpleTaskScheduler;
/**
* Namespace handler for the integration namespace.
@@ -24,25 +40,79 @@ import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
* @author Mark Fisher
* @author Marius Bogoevici
*/
public class IntegrationNamespaceHandler extends NamespaceHandlerSupport {
public class IntegrationNamespaceHandler implements NamespaceHandler {
private volatile boolean initializedContext;
private final NamespaceHandlerSupport delegate = new NamespaceHandlerDelegate();
public void init() {
registerBeanDefinitionParser("message-bus", new MessageBusParser());
registerBeanDefinitionParser("channel", new PointToPointChannelParser());
registerBeanDefinitionParser("thread-local-channel", new ThreadLocalChannelParser());
registerBeanDefinitionParser("publish-subscribe-channel", new PublishSubscribeChannelParser());
registerBeanDefinitionParser("service-activator", new ServiceActivatorParser());
registerBeanDefinitionParser("transformer", new TransformerParser());
registerBeanDefinitionParser("filter", new FilterParser());
registerBeanDefinitionParser("router", new RouterParser());
registerBeanDefinitionParser("splitter", new SplitterParser());
registerBeanDefinitionParser("aggregator", new AggregatorParser());
registerBeanDefinitionParser("resequencer", new ResequencerParser());
registerBeanDefinitionParser("inbound-channel-adapter", new MethodInvokingInboundChannelAdapterParser());
registerBeanDefinitionParser("outbound-channel-adapter", new MethodInvokingOutboundChannelAdapterParser());
registerBeanDefinitionParser("gateway", new GatewayParser());
registerBeanDefinitionParser("selector-chain", new SelectorChainParser());
registerBeanDefinitionParser("thread-pool-task-executor", new PoolExecutorParser());
this.delegate.init();
}
public BeanDefinition parse(Element element, ParserContext parserContext) {
if (!this.initializedContext) {
registerTaskSchedulerIfNecessary(parserContext.getRegistry());
this.initializedContext = true;
}
return this.delegate.parse(element, parserContext);
}
public BeanDefinitionHolder decorate(Node source, BeanDefinitionHolder definition, ParserContext parserContext) {
return this.delegate.decorate(source, definition, parserContext);
}
/**
* Register a TaskScheduler in the given BeanDefinitionRegistry if not yet present.
* The bean name for which this is checking is defined by the constant
* {@link IntegrationContextUtils#TASK_SCHEDULER_BEAN_NAME}.
*/
private static void registerTaskSchedulerIfNecessary(BeanDefinitionRegistry registry) {
if (!registry.containsBeanDefinition(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME)) {
RootBeanDefinition errorChannelDef = new RootBeanDefinition(QueueChannel.class);
BeanDefinitionHolder errorChannelHolder = new BeanDefinitionHolder(
errorChannelDef, IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME);
BeanDefinitionReaderUtils.registerBeanDefinition(errorChannelHolder, registry);
}
TaskExecutor taskExecutor = null;
if (!registry.containsBeanDefinition(IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME)) {
taskExecutor = IntegrationContextUtils.createTaskExecutor(2, 100, 0, "task-scheduler-");
BeanDefinitionBuilder schedulerBuilder = BeanDefinitionBuilder.genericBeanDefinition(SimpleTaskScheduler.class);
schedulerBuilder.addConstructorArgValue(taskExecutor);
BeanDefinitionBuilder errorHandlerBuilder = BeanDefinitionBuilder.genericBeanDefinition(MessagePublishingErrorHandler.class);
errorHandlerBuilder.addPropertyReference("defaultErrorChannel", IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME);
String errorHandlerBeanName = BeanDefinitionReaderUtils.registerWithGeneratedName(
errorHandlerBuilder.getBeanDefinition(), registry);
schedulerBuilder.addPropertyReference("errorHandler", errorHandlerBeanName);
BeanDefinitionHolder schedulerHolder = new BeanDefinitionHolder(
schedulerBuilder.getBeanDefinition(), IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME);
BeanDefinitionReaderUtils.registerBeanDefinition(schedulerHolder, registry);
}
}
private static class NamespaceHandlerDelegate extends NamespaceHandlerSupport {
public void init() {
registerBeanDefinitionParser("channel", new PointToPointChannelParser());
registerBeanDefinitionParser("thread-local-channel", new ThreadLocalChannelParser());
registerBeanDefinitionParser("publish-subscribe-channel", new PublishSubscribeChannelParser());
registerBeanDefinitionParser("service-activator", new ServiceActivatorParser());
registerBeanDefinitionParser("transformer", new TransformerParser());
registerBeanDefinitionParser("filter", new FilterParser());
registerBeanDefinitionParser("router", new RouterParser());
registerBeanDefinitionParser("splitter", new SplitterParser());
registerBeanDefinitionParser("aggregator", new AggregatorParser());
registerBeanDefinitionParser("resequencer", new ResequencerParser());
registerBeanDefinitionParser("inbound-channel-adapter", new MethodInvokingInboundChannelAdapterParser());
registerBeanDefinitionParser("outbound-channel-adapter", new MethodInvokingOutboundChannelAdapterParser());
registerBeanDefinitionParser("gateway", new GatewayParser());
registerBeanDefinitionParser("selector-chain", new SelectorChainParser());
registerBeanDefinitionParser("enable-annotations", new EnableAnnotationsParser());
registerBeanDefinitionParser("application-event-multicaster", new ApplicationEventMulticasterParser());
registerBeanDefinitionParser("thread-pool-task-executor", new PoolExecutorParser());
}
}
}

View File

@@ -23,19 +23,11 @@ import org.w3c.dom.Element;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
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.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.core.Conventions;
import org.springframework.core.task.TaskExecutor;
import org.springframework.integration.channel.MessagePublishingErrorHandler;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.context.IntegrationContextUtils;
import org.springframework.integration.scheduling.CronTrigger;
import org.springframework.integration.scheduling.IntervalTrigger;
import org.springframework.integration.scheduling.SimpleTaskScheduler;
import org.springframework.integration.scheduling.Trigger;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.util.Assert;
@@ -203,32 +195,4 @@ public abstract class IntegrationNamespaceUtils {
targetBuilder.addPropertyValue("transactionDefinition", txDefinition);
}
/**
* Register a TaskScheduler in the given BeanDefinitionRegistry if not yet present.
* The bean name for which this is checking is defined by the constant
* {@link IntegrationContextUtils#TASK_SCHEDULER_BEAN_NAME}.
*/
public static synchronized void registerTaskSchedulerIfNecessary(BeanDefinitionRegistry registry) {
if (!registry.containsBeanDefinition(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME)) {
RootBeanDefinition errorChannelDef = new RootBeanDefinition(QueueChannel.class);
BeanDefinitionHolder errorChannelHolder = new BeanDefinitionHolder(
errorChannelDef, IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME);
BeanDefinitionReaderUtils.registerBeanDefinition(errorChannelHolder, registry);
}
TaskExecutor taskExecutor = null;
if (!registry.containsBeanDefinition(IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME)) {
taskExecutor = IntegrationContextUtils.createTaskExecutor(2, 100, 0, "integration-main-");
BeanDefinitionBuilder schedulerBuilder = BeanDefinitionBuilder.genericBeanDefinition(SimpleTaskScheduler.class);
schedulerBuilder.addConstructorArgValue(taskExecutor);
BeanDefinitionBuilder errorHandlerBuilder = BeanDefinitionBuilder.genericBeanDefinition(MessagePublishingErrorHandler.class);
errorHandlerBuilder.addPropertyReference("defaultErrorChannel", IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME);
String errorHandlerBeanName = BeanDefinitionReaderUtils.registerWithGeneratedName(
errorHandlerBuilder.getBeanDefinition(), registry);
schedulerBuilder.addPropertyReference("errorHandler", errorHandlerBeanName);
BeanDefinitionHolder schedulerHolder = new BeanDefinitionHolder(
schedulerBuilder.getBeanDefinition(), IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME);
BeanDefinitionReaderUtils.registerBeanDefinition(schedulerHolder, registry);
}
}
}

View File

@@ -1,104 +0,0 @@
/*
* Copyright 2002-2008 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.integration.config.xml;
import java.util.concurrent.CopyOnWriteArraySet;
import org.w3c.dom.Element;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.context.event.SimpleApplicationEventMulticaster;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.core.task.TaskExecutor;
import org.springframework.integration.bus.ApplicationContextMessageBus;
import org.springframework.integration.config.annotation.MessagingAnnotationPostProcessor;
import org.springframework.integration.context.IntegrationContextUtils;
/**
* Parser for the &lt;message-bus&gt; element of the integration namespace.
*
* @author Mark Fisher
* @author Marius Bogoevici
*/
public class MessageBusParser extends AbstractSimpleBeanDefinitionParser {
private static final String MESSAGING_ANNOTATION_POST_PROCESSOR_BEAN_NAME =
"internal.MessagingAnnotationPostProcessor";
private static final String ASYNC_EVENT_MULTICASTER_ATTRIBUTE = "configure-async-event-multicaster";
@Override
protected Class<?> getBeanClass(Element element) {
return ApplicationContextMessageBus.class;
}
@Override
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
throws BeanDefinitionStoreException {
return "messageBus";
}
@Override
protected boolean isEligibleAttribute(String attributeName) {
return !ASYNC_EVENT_MULTICASTER_ATTRIBUTE.equals(attributeName) &&
!"enable-annotations".equals(attributeName) &&
super.isEligibleAttribute(attributeName);
}
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
super.doParse(element, parserContext, builder);
IntegrationNamespaceUtils.registerTaskSchedulerIfNecessary(parserContext.getRegistry());
if ("true".equals(element.getAttribute(ASYNC_EVENT_MULTICASTER_ATTRIBUTE).toLowerCase())) {
TaskExecutor taskExecutor = IntegrationContextUtils.createTaskExecutor(1, 10, 0, "event-multicaster-");
BeanDefinitionBuilder eventMulticasterBuilder = BeanDefinitionBuilder.genericBeanDefinition(
SimpleApplicationEventMulticaster.class);
eventMulticasterBuilder.addPropertyValue("taskExecutor", taskExecutor);
eventMulticasterBuilder.addPropertyValue("collectionClass", CopyOnWriteArraySet.class);
BeanDefinitionHolder holder = new BeanDefinitionHolder(eventMulticasterBuilder.getBeanDefinition(),
AbstractApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME);
BeanDefinitionReaderUtils.registerBeanDefinition(holder, parserContext.getRegistry());
}
this.addPostProcessors(element, parserContext);
}
/**
* Adds extra post-processors to the context, to inject the objects configured by the MessageBus
*/
private void addPostProcessors(Element element, ParserContext parserContext) {
if ("true".equals(element.getAttribute("enable-annotations").toLowerCase())) {
this.registerMessagingAnnotationPostProcessor(parserContext);
}
}
private void registerMessagingAnnotationPostProcessor(ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MessagingAnnotationPostProcessor.class);
builder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
parserContext.getRegistry().registerBeanDefinition(
MESSAGING_ANNOTATION_POST_PROCESSOR_BEAN_NAME, builder.getBeanDefinition());
}
}

View File

@@ -16,15 +16,24 @@
]]></xsd:documentation>
</xsd:annotation>
<xsd:element name="message-bus">
<xsd:element name="enable-annotations">
<xsd:annotation>
<xsd:documentation>
Enables annotation support for Message Endpoints.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="application-event-multicaster">
<xsd:complexType>
<xsd:annotation>
<xsd:documentation>
Defines the Message Bus for this Application Context.
Defines the ApplicationEventMulticaster to use for this ApplicationContext.
The "task-executor" reference is optional. If not provided, an instance of
ThreadPoolTaskExecutor will be created by default.
</xsd:documentation>
</xsd:annotation>
<xsd:attribute name="enable-annotations" type="xsd:boolean"/>
<xsd:attribute name="configure-async-event-multicaster" type="xsd:boolean"/>
<xsd:attribute name="task-executor"/>
</xsd:complexType>
</xsd:element>