Repository: camel Updated Branches: refs/heads/master 308c9d4e6 -> c079447c0
CAMEL-7156: SpringCamelContext should shutdown eager to shutdown cleanly. Introduced shutdownEager option to turn back old behavior for special use-case relying on old way. Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/c079447c Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/c079447c Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/c079447c Branch: refs/heads/master Commit: c079447c0aa6e316a9914f2413c00b9bab3cabdb Parents: 308c9d4 Author: Claus Ibsen <davscl...@apache.org> Authored: Fri Feb 28 14:54:00 2014 +0100 Committer: Claus Ibsen <davscl...@apache.org> Committed: Fri Feb 28 15:34:40 2014 +0100 ---------------------------------------------------------------------- .../camel/spring/CamelContextFactoryBean.java | 22 +++++++ .../apache/camel/spring/SpringCamelContext.java | 33 +++++++++++ .../java/org/apache/camel/spring/BeanA.java | 47 +++++++++++++++ .../java/org/apache/camel/spring/BeanB.java | 47 +++++++++++++++ .../java/org/apache/camel/spring/BeanC.java | 47 +++++++++++++++ .../apache/camel/spring/ShutdownOrderBean.java | 42 ++++++++++++++ ...SpringCamelContextShutdownAfterBeanTest.java | 60 ++++++++++++++++++++ ...pringCamelContextShutdownBeforeBeanTest.java | 58 +++++++++++++++++++ .../SpringCamelContextShutdownAfterBeanTest.xml | 54 ++++++++++++++++++ ...SpringCamelContextShutdownBeforeBeanTest.xml | 53 +++++++++++++++++ 10 files changed, 463 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/c079447c/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java ---------------------------------------------------------------------- diff --git a/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java b/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java index 7663e8b..881ef75 100644 --- a/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java +++ b/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java @@ -55,6 +55,7 @@ import org.apache.camel.model.dataformat.DataFormatsDefinition; import org.apache.camel.spi.PackageScanFilter; import org.apache.camel.spi.Registry; import org.apache.camel.spring.spi.BridgePropertyPlaceholderConfigurer; +import org.apache.camel.util.CamelContextHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.DisposableBean; @@ -100,6 +101,8 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Spr @XmlAttribute(required = false) private String autoStartup; @XmlAttribute(required = false) + private String shutdownEager; + @XmlAttribute(required = false) private String useMDCLogging; @XmlAttribute(required = false) private String useBreadcrumb; @@ -237,6 +240,17 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Spr } } + @Override + public void afterPropertiesSet() throws Exception { + super.afterPropertiesSet(); + + Boolean shutdownEager = CamelContextHelper.parseBoolean(getContext(), getShutdownEager()); + if (shutdownEager != null) { + LOG.debug("Using shutdownEager: " + shutdownEager); + getContext().setShutdownEager(shutdownEager); + } + } + protected void initCustomRegistry(SpringCamelContext context) { Registry registry = getBeanForType(Registry.class); if (registry != null) { @@ -533,6 +547,14 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Spr this.autoStartup = autoStartup; } + public String getShutdownEager() { + return shutdownEager; + } + + public void setShutdownEager(String shutdownEager) { + this.shutdownEager = shutdownEager; + } + public String getUseMDCLogging() { return useMDCLogging; } http://git-wip-us.apache.org/repos/asf/camel/blob/c079447c/components/camel-spring/src/main/java/org/apache/camel/spring/SpringCamelContext.java ---------------------------------------------------------------------- diff --git a/components/camel-spring/src/main/java/org/apache/camel/spring/SpringCamelContext.java b/components/camel-spring/src/main/java/org/apache/camel/spring/SpringCamelContext.java index cf97cc6..ce422ea 100644 --- a/components/camel-spring/src/main/java/org/apache/camel/spring/SpringCamelContext.java +++ b/components/camel-spring/src/main/java/org/apache/camel/spring/SpringCamelContext.java @@ -37,6 +37,7 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationEvent; import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.event.ContextClosedEvent; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.context.event.ContextStoppedEvent; import org.springframework.context.support.ClassPathXmlApplicationContext; @@ -60,6 +61,7 @@ public class SpringCamelContext extends DefaultCamelContext implements Initializ private static final ThreadLocal<Boolean> NO_START = new ThreadLocal<Boolean>(); private ApplicationContext applicationContext; private EventComponent eventComponent; + private boolean shutdownEager = true; public SpringCamelContext() { } @@ -119,7 +121,17 @@ public class SpringCamelContext extends DefaultCamelContext implements Initializ } catch (Exception e) { throw wrapRuntimeCamelException(e); } + } else if (event instanceof ContextClosedEvent) { + // ContextClosedEvent is emitted when Spring is about to be shutdown + if (isShutdownEager()) { + try { + maybeStop(); + } catch (Exception e) { + throw wrapRuntimeCamelException(e); + } + } } else if (event instanceof ContextStoppedEvent) { + // ContextStoppedEvent is emitted when Spring is end of shutdown try { maybeStop(); } catch (Exception e) { @@ -172,6 +184,27 @@ public class SpringCamelContext extends DefaultCamelContext implements Initializ // noop } + /** + * Whether to shutdown this {@link org.apache.camel.spring.SpringCamelContext} eager (first) + * when Spring {@link org.springframework.context.ApplicationContext} is being stopped. + * <p/> + * <b>Important:</b> This option is default <tt>true</tt> which ensures we shutdown Camel + * before other beans. Setting this to <tt>false</tt> restores old behavior in earlier + * Camel releases, which can be used for special cases to behave as before. + * + * @return <tt>true</tt> to shutdown eager (first), <tt>false</tt> to shutdown last + */ + public boolean isShutdownEager() { + return shutdownEager; + } + + /** + * @see #isShutdownEager() + */ + public void setShutdownEager(boolean shutdownEager) { + this.shutdownEager = shutdownEager; + } + // Implementation methods // ----------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/c079447c/components/camel-spring/src/test/java/org/apache/camel/spring/BeanA.java ---------------------------------------------------------------------- diff --git a/components/camel-spring/src/test/java/org/apache/camel/spring/BeanA.java b/components/camel-spring/src/test/java/org/apache/camel/spring/BeanA.java new file mode 100644 index 0000000..f771851 --- /dev/null +++ b/components/camel-spring/src/test/java/org/apache/camel/spring/BeanA.java @@ -0,0 +1,47 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.camel.spring; + +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.InitializingBean; + +public class BeanA implements InitializingBean, DisposableBean { + + private ShutdownOrderBean shutdownOrderBean; + + public ShutdownOrderBean getShutdownOrderBean() { + return shutdownOrderBean; + } + + public void setShutdownOrderBean(ShutdownOrderBean shutdownOrderBean) { + this.shutdownOrderBean = shutdownOrderBean; + } + + public String foo(String s) { + return "a" + s; + } + + @Override + public void destroy() throws Exception { + shutdownOrderBean.shutdown("a"); + } + + @Override + public void afterPropertiesSet() throws Exception { + shutdownOrderBean.start("a"); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/c079447c/components/camel-spring/src/test/java/org/apache/camel/spring/BeanB.java ---------------------------------------------------------------------- diff --git a/components/camel-spring/src/test/java/org/apache/camel/spring/BeanB.java b/components/camel-spring/src/test/java/org/apache/camel/spring/BeanB.java new file mode 100644 index 0000000..6177796 --- /dev/null +++ b/components/camel-spring/src/test/java/org/apache/camel/spring/BeanB.java @@ -0,0 +1,47 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.camel.spring; + +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.InitializingBean; + +public class BeanB implements InitializingBean, DisposableBean { + + private ShutdownOrderBean shutdownOrderBean; + + public ShutdownOrderBean getShutdownOrderBean() { + return shutdownOrderBean; + } + + public void setShutdownOrderBean(ShutdownOrderBean shutdownOrderBean) { + this.shutdownOrderBean = shutdownOrderBean; + } + + public String foo(String s) { + return "b" + s; + } + + @Override + public void destroy() throws Exception { + shutdownOrderBean.shutdown("b"); + } + + @Override + public void afterPropertiesSet() throws Exception { + shutdownOrderBean.start("b"); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/c079447c/components/camel-spring/src/test/java/org/apache/camel/spring/BeanC.java ---------------------------------------------------------------------- diff --git a/components/camel-spring/src/test/java/org/apache/camel/spring/BeanC.java b/components/camel-spring/src/test/java/org/apache/camel/spring/BeanC.java new file mode 100644 index 0000000..d9c44c3 --- /dev/null +++ b/components/camel-spring/src/test/java/org/apache/camel/spring/BeanC.java @@ -0,0 +1,47 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.camel.spring; + +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.InitializingBean; + +public class BeanC implements InitializingBean, DisposableBean { + + private ShutdownOrderBean shutdownOrderBean; + + public ShutdownOrderBean getShutdownOrderBean() { + return shutdownOrderBean; + } + + public void setShutdownOrderBean(ShutdownOrderBean shutdownOrderBean) { + this.shutdownOrderBean = shutdownOrderBean; + } + + public String foo(String s) { + return "c" + s; + } + + @Override + public void destroy() throws Exception { + shutdownOrderBean.shutdown("c"); + } + + @Override + public void afterPropertiesSet() throws Exception { + shutdownOrderBean.start("c"); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/c079447c/components/camel-spring/src/test/java/org/apache/camel/spring/ShutdownOrderBean.java ---------------------------------------------------------------------- diff --git a/components/camel-spring/src/test/java/org/apache/camel/spring/ShutdownOrderBean.java b/components/camel-spring/src/test/java/org/apache/camel/spring/ShutdownOrderBean.java new file mode 100644 index 0000000..5fa708c --- /dev/null +++ b/components/camel-spring/src/test/java/org/apache/camel/spring/ShutdownOrderBean.java @@ -0,0 +1,42 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.camel.spring; + +import java.util.ArrayList; +import java.util.List; + +public class ShutdownOrderBean { + + private List start = new ArrayList(); + private List shutdown = new ArrayList(); + + public void start(String name) { + start.add(name); + + } + public void shutdown(String name) { + shutdown.add(name); + } + + public List getStart() { + return start; + } + + public List getShutdown() { + return shutdown; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/c079447c/components/camel-spring/src/test/java/org/apache/camel/spring/SpringCamelContextShutdownAfterBeanTest.java ---------------------------------------------------------------------- diff --git a/components/camel-spring/src/test/java/org/apache/camel/spring/SpringCamelContextShutdownAfterBeanTest.java b/components/camel-spring/src/test/java/org/apache/camel/spring/SpringCamelContextShutdownAfterBeanTest.java new file mode 100644 index 0000000..8e9341b --- /dev/null +++ b/components/camel-spring/src/test/java/org/apache/camel/spring/SpringCamelContextShutdownAfterBeanTest.java @@ -0,0 +1,60 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.camel.spring; + +import org.apache.camel.component.mock.MockEndpoint; +import org.springframework.context.support.AbstractXmlApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class SpringCamelContextShutdownAfterBeanTest extends SpringTestSupport { + + @Override + protected AbstractXmlApplicationContext createApplicationContext() { + return new ClassPathXmlApplicationContext("org/apache/camel/spring/SpringCamelContextShutdownAfterBeanTest.xml"); + } + + public void testShutdown() throws Exception { + // you may have errors during shutdown, which you can see from the log + + ShutdownOrderBean order = (ShutdownOrderBean) context.getRegistry().lookupByName("order"); + + assertEquals(3, order.getStart().size()); + assertEquals(0, order.getShutdown().size()); + assertEquals("a", order.getStart().get(0)); + assertEquals("b", order.getStart().get(1)); + assertEquals("c", order.getStart().get(2)); + + MockEndpoint first = getMockEndpoint("mock:first"); + first.expectedMessageCount(5); + + for (int i = 0; i < 5; i++) { + template.sendBody("seda:start", "Hello World"); + } + + first.assertIsSatisfied(); + + // stop spring to cause shutdown of Camel + applicationContext.close(); + applicationContext.destroy(); + + assertEquals(3, order.getStart().size()); + assertEquals(3, order.getShutdown().size()); + assertEquals("c", order.getShutdown().get(0)); + assertEquals("b", order.getShutdown().get(1)); + assertEquals("a", order.getShutdown().get(2)); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/c079447c/components/camel-spring/src/test/java/org/apache/camel/spring/SpringCamelContextShutdownBeforeBeanTest.java ---------------------------------------------------------------------- diff --git a/components/camel-spring/src/test/java/org/apache/camel/spring/SpringCamelContextShutdownBeforeBeanTest.java b/components/camel-spring/src/test/java/org/apache/camel/spring/SpringCamelContextShutdownBeforeBeanTest.java new file mode 100644 index 0000000..4680321 --- /dev/null +++ b/components/camel-spring/src/test/java/org/apache/camel/spring/SpringCamelContextShutdownBeforeBeanTest.java @@ -0,0 +1,58 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.camel.spring; + +import org.apache.camel.component.mock.MockEndpoint; +import org.springframework.context.support.AbstractXmlApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class SpringCamelContextShutdownBeforeBeanTest extends SpringTestSupport { + + @Override + protected AbstractXmlApplicationContext createApplicationContext() { + return new ClassPathXmlApplicationContext("org/apache/camel/spring/SpringCamelContextShutdownBeforeBeanTest.xml"); + } + + public void testShutdown() throws Exception { + ShutdownOrderBean order = (ShutdownOrderBean) context.getRegistry().lookupByName("order"); + + assertEquals(3, order.getStart().size()); + assertEquals(0, order.getShutdown().size()); + assertEquals("a", order.getStart().get(0)); + assertEquals("b", order.getStart().get(1)); + assertEquals("c", order.getStart().get(2)); + + MockEndpoint first = getMockEndpoint("mock:first"); + first.expectedMessageCount(5); + + for (int i = 0; i < 5; i++) { + template.sendBody("seda:start", "Hello World"); + } + + first.assertIsSatisfied(); + + // stop spring to cause shutdown of Camel + applicationContext.close(); + applicationContext.destroy(); + + assertEquals(3, order.getStart().size()); + assertEquals(3, order.getShutdown().size()); + assertEquals("c", order.getShutdown().get(0)); + assertEquals("b", order.getShutdown().get(1)); + assertEquals("a", order.getShutdown().get(2)); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/c079447c/components/camel-spring/src/test/resources/org/apache/camel/spring/SpringCamelContextShutdownAfterBeanTest.xml ---------------------------------------------------------------------- diff --git a/components/camel-spring/src/test/resources/org/apache/camel/spring/SpringCamelContextShutdownAfterBeanTest.xml b/components/camel-spring/src/test/resources/org/apache/camel/spring/SpringCamelContextShutdownAfterBeanTest.xml new file mode 100644 index 0000000..ad087e6 --- /dev/null +++ b/components/camel-spring/src/test/resources/org/apache/camel/spring/SpringCamelContextShutdownAfterBeanTest.xml @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd + http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd + "> + + <bean id="order" class="org.apache.camel.spring.ShutdownOrderBean"/> + + <bean id="a" class="org.apache.camel.spring.BeanA"> + <property name="shutdownOrderBean" ref="order"/> + </bean> + <bean id="b" class="org.apache.camel.spring.BeanB"> + <property name="shutdownOrderBean" ref="order"/> + </bean> + + <!-- shutdown eager is false, to shutdown in last/default order --> + <camelContext id="myCamel" shutdownEager="false" xmlns="http://camel.apache.org/schema/spring"> + <route> + <from uri="seda:start"/> + <to uri="bean:a?cache=false"/> + <to uri="bean:b?cache=false"/> + <to uri="mock:first"/> + <delay> + <constant>1000</constant> + </delay> + <to uri="bean:c?cache=false"/> + <to uri="mock:result"/> + </route> + </camelContext> + + <!-- this bean may shutdown before Camel and cause problem with in-flight messages still in need of this bean --> + <bean id="c" class="org.apache.camel.spring.BeanC"> + <property name="shutdownOrderBean" ref="order"/> + </bean> + +</beans> http://git-wip-us.apache.org/repos/asf/camel/blob/c079447c/components/camel-spring/src/test/resources/org/apache/camel/spring/SpringCamelContextShutdownBeforeBeanTest.xml ---------------------------------------------------------------------- diff --git a/components/camel-spring/src/test/resources/org/apache/camel/spring/SpringCamelContextShutdownBeforeBeanTest.xml b/components/camel-spring/src/test/resources/org/apache/camel/spring/SpringCamelContextShutdownBeforeBeanTest.xml new file mode 100644 index 0000000..f506a8e --- /dev/null +++ b/components/camel-spring/src/test/resources/org/apache/camel/spring/SpringCamelContextShutdownBeforeBeanTest.xml @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd + http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd + "> + + <bean id="order" class="org.apache.camel.spring.ShutdownOrderBean"/> + + <bean id="a" class="org.apache.camel.spring.BeanA"> + <property name="shutdownOrderBean" ref="order"/> + </bean> + <bean id="b" class="org.apache.camel.spring.BeanB"> + <property name="shutdownOrderBean" ref="order"/> + </bean> + + <camelContext id="myCamel" xmlns="http://camel.apache.org/schema/spring"> + <route> + <from uri="seda:start"/> + <to uri="bean:a?cache=false"/> + <to uri="bean:b?cache=false"/> + <to uri="mock:first"/> + <delay> + <constant>1000</constant> + </delay> + <to uri="bean:c?cache=false"/> + <to uri="mock:result"/> + </route> + </camelContext> + + <!-- order of where beans is define should not matter --> + <bean id="c" class="org.apache.camel.spring.BeanC"> + <property name="shutdownOrderBean" ref="order"/> + </bean> + +</beans>