diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/config/ConsumerEndpointFactoryBean.java b/org.springframework.integration/src/main/java/org/springframework/integration/config/ConsumerEndpointFactoryBean.java
index fd6c2bb702..8a3ddafb71 100644
--- a/org.springframework.integration/src/main/java/org/springframework/integration/config/ConsumerEndpointFactoryBean.java
+++ b/org.springframework.integration/src/main/java/org/springframework/integration/config/ConsumerEndpointFactoryBean.java
@@ -138,6 +138,7 @@ public class ConsumerEndpointFactoryBean implements FactoryBean, BeanFactoryAwar
pollingConsumer.setTaskExecutor(this.pollerMetadata.getTaskExecutor());
pollingConsumer.setTransactionManager(this.pollerMetadata.getTransactionManager());
pollingConsumer.setTransactionDefinition(this.pollerMetadata.getTransactionDefinition());
+ pollingConsumer.setAdviceChain(this.pollerMetadata.getAdviceChain());
this.endpoint = pollingConsumer;
}
else {
diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/config/xml/PollerParser.java b/org.springframework.integration/src/main/java/org/springframework/integration/config/xml/PollerParser.java
index a4054a4e44..92a6941b69 100644
--- a/org.springframework.integration/src/main/java/org/springframework/integration/config/xml/PollerParser.java
+++ b/org.springframework.integration/src/main/java/org/springframework/integration/config/xml/PollerParser.java
@@ -19,11 +19,18 @@ package org.springframework.integration.config.xml;
import java.util.concurrent.TimeUnit;
import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
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.config.RuntimeBeanReference;
+import org.springframework.beans.factory.parsing.BeanComponentDefinition;
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.support.ManagedList;
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.context.IntegrationContextUtils;
@@ -69,6 +76,10 @@ public class PollerParser extends AbstractBeanDefinitionParser {
}
configureTrigger(element, metadataBuilder, parserContext);
IntegrationNamespaceUtils.setValueIfAttributeDefined(metadataBuilder, element, "max-messages-per-poll");
+ Element adviceChainElement = DomUtils.getChildElementByTagName(element, "advice-chain");
+ if (adviceChainElement != null) {
+ configureAdviceChain(adviceChainElement, metadataBuilder, parserContext);
+ }
Element txElement = DomUtils.getChildElementByTagName(element, "transactional");
if (txElement != null) {
configureTransactionAttributes(txElement, metadataBuilder);
@@ -142,4 +153,39 @@ public class PollerParser extends AbstractBeanDefinitionParser {
targetBuilder.addPropertyValue("transactionDefinition", txDefinition);
}
+ /**
+ * Parses the 'advice-chain' element's sub-elements.
+ */
+ @SuppressWarnings("unchecked")
+ private void configureAdviceChain(Element adviceChainElement, BeanDefinitionBuilder targetBuilder, ParserContext parserContext) {
+ ManagedList adviceChain = new ManagedList();
+ NodeList childNodes = adviceChainElement.getChildNodes();
+ for (int i = 0; i < childNodes.getLength(); i++) {
+ Node child = childNodes.item(i);
+ if (child.getNodeType() == Node.ELEMENT_NODE) {
+ Element childElement = (Element) child;
+ String localName = child.getLocalName();
+ if ("bean".equals(localName)) {
+ BeanDefinitionHolder holder = parserContext.getDelegate().parseBeanDefinitionElement(
+ childElement, targetBuilder.getBeanDefinition());
+ parserContext.registerBeanComponent(new BeanComponentDefinition(holder));
+ adviceChain.add(new RuntimeBeanReference(holder.getBeanName()));
+ }
+ else if ("ref".equals(localName)) {
+ String ref = childElement.getAttribute("bean");
+ adviceChain.add(new RuntimeBeanReference(ref));
+ }
+ else {
+ BeanDefinition customBeanDefinition = parserContext.getDelegate().parseCustomElement(
+ childElement, targetBuilder.getBeanDefinition());
+ if (customBeanDefinition == null) {
+ parserContext.getReaderContext().error(
+ "failed to parse custom element '" + localName + "'", childElement);
+ }
+ }
+ }
+ }
+ targetBuilder.addPropertyValue("adviceChain", adviceChain);
+ }
+
}
diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/config/xml/spring-integration-1.0.xsd b/org.springframework.integration/src/main/java/org/springframework/integration/config/xml/spring-integration-1.0.xsd
index d906d7bd00..e6869d2ac8 100644
--- a/org.springframework.integration/src/main/java/org/springframework/integration/config/xml/spring-integration-1.0.xsd
+++ b/org.springframework.integration/src/main/java/org/springframework/integration/config/xml/spring-integration-1.0.xsd
@@ -368,9 +368,12 @@
-
+
+
+
+
@@ -424,6 +427,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/endpoint/AbstractPollingEndpoint.java b/org.springframework.integration/src/main/java/org/springframework/integration/endpoint/AbstractPollingEndpoint.java
index 0fb1256c33..fea979e1ab 100644
--- a/org.springframework.integration/src/main/java/org/springframework/integration/endpoint/AbstractPollingEndpoint.java
+++ b/org.springframework.integration/src/main/java/org/springframework/integration/endpoint/AbstractPollingEndpoint.java
@@ -119,8 +119,12 @@ public abstract class AbstractPollingEndpoint extends AbstractEndpoint implement
}
public void setAdviceChain(List adviceChain) {
- this.adviceChain.clear();
- this.adviceChain.addAll(adviceChain);
+ synchronized (this.adviceChain) {
+ this.adviceChain.clear();
+ if (adviceChain != null) {
+ this.adviceChain.addAll(adviceChain);
+ }
+ }
}
private TransactionTemplate getTransactionTemplate() {
diff --git a/org.springframework.integration/src/main/java/org/springframework/integration/scheduling/PollerMetadata.java b/org.springframework.integration/src/main/java/org/springframework/integration/scheduling/PollerMetadata.java
index 97b8670c80..9162230d1e 100644
--- a/org.springframework.integration/src/main/java/org/springframework/integration/scheduling/PollerMetadata.java
+++ b/org.springframework.integration/src/main/java/org/springframework/integration/scheduling/PollerMetadata.java
@@ -16,6 +16,10 @@
package org.springframework.integration.scheduling;
+import java.util.List;
+
+import org.aopalliance.aop.Advice;
+
import org.springframework.core.task.TaskExecutor;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
@@ -31,6 +35,8 @@ public class PollerMetadata {
private volatile long receiveTimeout = 1000;
+ private List adviceChain;
+
private volatile TaskExecutor taskExecutor;
private volatile PlatformTransactionManager transactionManager;
@@ -62,6 +68,14 @@ public class PollerMetadata {
return this.receiveTimeout;
}
+ public void setAdviceChain(List adviceChain) {
+ this.adviceChain = adviceChain;
+ }
+
+ public List getAdviceChain() {
+ return this.adviceChain;
+ }
+
public void setTaskExecutor(TaskExecutor taskExecutor) {
this.taskExecutor = taskExecutor;
}
diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/config/xml/PollerParserTests.java b/org.springframework.integration/src/test/java/org/springframework/integration/config/xml/PollerParserTests.java
index 23c7fb96aa..1af32aff97 100644
--- a/org.springframework.integration/src/test/java/org/springframework/integration/config/xml/PollerParserTests.java
+++ b/org.springframework.integration/src/test/java/org/springframework/integration/config/xml/PollerParserTests.java
@@ -25,6 +25,7 @@ import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.context.IntegrationContextUtils;
+import org.springframework.integration.scheduling.PollerMetadata;
/**
* @author Mark Fisher
@@ -62,4 +63,19 @@ public class PollerParserTests {
"topLevelPollerWithoutId.xml", PollerParserTests.class);
}
+ @Test
+ public void pollerWithAdviceChain() {
+ ApplicationContext context = new ClassPathXmlApplicationContext(
+ "pollerWithAdviceChain.xml", PollerParserTests.class);
+ Object poller = context.getBean("poller");
+ assertNotNull(poller);
+ PollerMetadata metadata = (PollerMetadata) poller;
+ assertNotNull(metadata.getAdviceChain());
+ assertEquals(3, metadata.getAdviceChain().size());
+ assertEquals(context.getBean("adviceBean1"), metadata.getAdviceChain().get(0));
+ assertEquals(TestAdviceBean.class, metadata.getAdviceChain().get(1).getClass());
+ assertEquals(2, ((TestAdviceBean) metadata.getAdviceChain().get(1)).getId());
+ assertEquals(context.getBean("adviceBean3"), metadata.getAdviceChain().get(2));
+ }
+
}
diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/config/xml/TestAdviceBean.java b/org.springframework.integration/src/test/java/org/springframework/integration/config/xml/TestAdviceBean.java
new file mode 100644
index 0000000000..afa0328b98
--- /dev/null
+++ b/org.springframework.integration/src/test/java/org/springframework/integration/config/xml/TestAdviceBean.java
@@ -0,0 +1,43 @@
+/*
+ * 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.lang.reflect.Method;
+
+import org.springframework.aop.MethodBeforeAdvice;
+
+/**
+ * @author Mark Fisher
+ */
+public class TestAdviceBean implements MethodBeforeAdvice {
+
+ private final int id;
+
+
+ public TestAdviceBean(int id) {
+ this.id = id;
+ }
+
+
+ public int getId() {
+ return this.id;
+ }
+
+ public void before(Method method, Object[] args, Object target) throws Throwable {
+ }
+
+}
diff --git a/org.springframework.integration/src/test/java/org/springframework/integration/config/xml/pollerWithAdviceChain.xml b/org.springframework.integration/src/test/java/org/springframework/integration/config/xml/pollerWithAdviceChain.xml
new file mode 100644
index 0000000000..8e40db5414
--- /dev/null
+++ b/org.springframework.integration/src/test/java/org/springframework/integration/config/xml/pollerWithAdviceChain.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+