Author: davsclaus
Date: Sun Dec 20 16:33:19 2009
New Revision: 892606
URL: http://svn.apache.org/viewvc?rev=892606&view=rev
Log:
CAMEL-2199: Added log to the DSL for easy human logs based Simple language to
extract parts from message etc.
Added:
camel/trunk/camel-core/src/main/java/org/apache/camel/model/LogDefinition.java
- copied, changed from r892586,
camel/trunk/camel-core/src/main/java/org/apache/camel/model/LoopDefinition.java
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/LogProcessor.java
(with props)
camel/trunk/camel-core/src/test/java/org/apache/camel/processor/LogProcessorTest.java
(with props)
camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringLogProcessorTest.java
- copied, changed from r892586,
camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringConvertBodyTest.java
camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/logProcessorTest.xml
- copied, changed from r892586,
camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/convertBody.xml
Modified:
camel/trunk/camel-core/src/main/java/org/apache/camel/model/LoopDefinition.java
camel/trunk/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java
camel/trunk/camel-core/src/main/java/org/apache/camel/model/language/ExpressionDefinition.java
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/MarshalProcessor.java
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/UnmarshalProcessor.java
camel/trunk/camel-core/src/main/resources/org/apache/camel/model/jaxb.index
Copied:
camel/trunk/camel-core/src/main/java/org/apache/camel/model/LogDefinition.java
(from r892586,
camel/trunk/camel-core/src/main/java/org/apache/camel/model/LoopDefinition.java)
URL:
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/LogDefinition.java?p2=camel/trunk/camel-core/src/main/java/org/apache/camel/model/LogDefinition.java&p1=camel/trunk/camel-core/src/main/java/org/apache/camel/model/LoopDefinition.java&r1=892586&r2=892606&rev=892606&view=diff
==============================================================================
---
camel/trunk/camel-core/src/main/java/org/apache/camel/model/LoopDefinition.java
(original)
+++
camel/trunk/camel-core/src/main/java/org/apache/camel/model/LogDefinition.java
Sun Dec 20 16:33:19 2009
@@ -16,68 +16,104 @@
*/
package org.apache.camel.model;
+import java.util.Collections;
+import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import org.apache.camel.Expression;
+import org.apache.camel.LoggingLevel;
import org.apache.camel.Processor;
-import org.apache.camel.builder.ExpressionClause;
-import org.apache.camel.model.language.ExpressionDefinition;
-import org.apache.camel.processor.LoopProcessor;
+import org.apache.camel.processor.LogProcessor;
+import org.apache.camel.processor.Logger;
import org.apache.camel.spi.RouteContext;
+import org.apache.camel.util.ObjectHelper;
/**
- * Represents an XML <loop/> element
+ * Represents an XML <log/> element
*
* @version $Revision$
*/
-...@xmlrootelement(name = "loop")
+...@xmlrootelement(name = "log")
@XmlAccessorType(XmlAccessType.FIELD)
-public class LoopDefinition extends ExpressionNode implements Block {
+public class LogDefinition extends ProcessorDefinition {
- public LoopDefinition() {
- }
+ @XmlAttribute
+ private String message;
+ @XmlAttribute
+ private LoggingLevel loggingLevel = LoggingLevel.INFO;
+ @XmlAttribute
+ private String logName;
- public LoopDefinition(Expression expression) {
- super(expression);
+ public LogDefinition() {
}
- public LoopDefinition(ExpressionDefinition expression) {
- super(expression);
+ public LogDefinition(String message) {
+ this.message = message;
}
- public void setExpression(Expression expr) {
- if (expr != null) {
- setExpression(new ExpressionDefinition(expr));
- }
- }
-
@Override
public String toString() {
- return "Loop[" + getExpression() + " -> " + getOutputs() + "]";
+ return "Log[" + message + "]";
}
-
+
@Override
public String getShortName() {
- return "loop";
+ return "log";
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public List<ProcessorDefinition> getOutputs() {
+ return Collections.EMPTY_LIST;
}
@Override
public Processor createProcessor(RouteContext routeContext) throws
Exception {
- return new LoopProcessor(
- getExpression().createExpression(routeContext),
- routeContext.createProcessor(this));
- }
-
- // Fluent API
- //-------------------------------------------------------------------------
-
- /**
- * Set the expression that LoopType will use
- * @return the builder
- */
- public ExpressionClause<LoopDefinition> expression() {
- return ExpressionClause.createAndSetExpression(this);
+ ObjectHelper.notEmpty(message, "message", this);
+
+ // use simple language for the message string to give it more power
+ Expression exp =
routeContext.getCamelContext().resolveLanguage("simple").createExpression(message);
+
+ String name = getLogName();
+ if (name == null) {
+ name = routeContext.getRoute().getId();
+ }
+ Logger logger = new Logger(name, getLoggingLevel());
+
+ return new LogProcessor(exp, logger);
+ }
+
+ @Override
+ public void addOutput(ProcessorDefinition processorType) {
+ // add outputs on parent as this log does not support outputs
+ getParent().addOutput(processorType);
}
-}
+
+ public LoggingLevel getLoggingLevel() {
+ return loggingLevel;
+ }
+
+ public void setLoggingLevel(LoggingLevel loggingLevel) {
+ this.loggingLevel = loggingLevel;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String getLogName() {
+ return logName;
+ }
+
+ public void setLogName(String logName) {
+ this.logName = logName;
+ }
+
+}
\ No newline at end of file
Modified:
camel/trunk/camel-core/src/main/java/org/apache/camel/model/LoopDefinition.java
URL:
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/LoopDefinition.java?rev=892606&r1=892605&r2=892606&view=diff
==============================================================================
---
camel/trunk/camel-core/src/main/java/org/apache/camel/model/LoopDefinition.java
(original)
+++
camel/trunk/camel-core/src/main/java/org/apache/camel/model/LoopDefinition.java
Sun Dec 20 16:33:19 2009
@@ -34,7 +34,7 @@
*/
@XmlRootElement(name = "loop")
@XmlAccessorType(XmlAccessType.FIELD)
-public class LoopDefinition extends ExpressionNode implements Block {
+public class LoopDefinition extends ExpressionNode {
public LoopDefinition() {
}
Modified:
camel/trunk/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java
URL:
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java?rev=892606&r1=892605&r2=892606&view=diff
==============================================================================
---
camel/trunk/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java
(original)
+++
camel/trunk/camel-core/src/main/java/org/apache/camel/model/ProcessorDefinition.java
Sun Dec 20 16:33:19 2009
@@ -34,6 +34,7 @@
import org.apache.camel.Endpoint;
import org.apache.camel.ExchangePattern;
import org.apache.camel.Expression;
+import org.apache.camel.LoggingLevel;
import org.apache.camel.Predicate;
import org.apache.camel.Processor;
import org.apache.camel.Route;
@@ -43,6 +44,7 @@
import org.apache.camel.builder.ExpressionBuilder;
import org.apache.camel.builder.ExpressionClause;
import org.apache.camel.builder.ProcessorBuilder;
+import org.apache.camel.language.simple.SimpleLanguage;
import org.apache.camel.model.language.ConstantExpression;
import org.apache.camel.model.language.ExpressionDefinition;
import org.apache.camel.model.language.LanguageExpression;
@@ -1047,6 +1049,51 @@
}
/**
+ * Creates a log message to be logged at INFO level.
+ *
+ * @param message the log message, (you can use {...@link
org.apache.camel.language.simple.SimpleLanguage} syntax)
+ * @return the builder
+ */
+ @SuppressWarnings("unchecked")
+ public Type log(String message) {
+ LogDefinition answer = new LogDefinition(message);
+ addOutput(answer);
+ return (Type) this;
+ }
+
+ /**
+ * Creates a log message to be logged at the given level.
+ *
+ * @param loggingLevel the logging level to use
+ * @param message the log message, (you can use {...@link
org.apache.camel.language.simple.SimpleLanguage} syntax)
+ * @return the builder
+ */
+ @SuppressWarnings("unchecked")
+ public Type log(LoggingLevel loggingLevel, String message) {
+ LogDefinition answer = new LogDefinition(message);
+ answer.setLoggingLevel(loggingLevel);
+ addOutput(answer);
+ return (Type) this;
+ }
+
+ /**
+ * Creates a log message to be logged at the given level and name.
+ *
+ * @param loggingLevel the logging level to use
+ * @param logName the log name to use
+ * @param message the log message, (you can use {...@link
org.apache.camel.language.simple.SimpleLanguage} syntax)
+ * @return the builder
+ */
+ @SuppressWarnings("unchecked")
+ public Type log(LoggingLevel loggingLevel, String logName, String message)
{
+ LogDefinition answer = new LogDefinition(message);
+ answer.setLoggingLevel(loggingLevel);
+ answer.setLogName(logName);
+ addOutput(answer);
+ return (Type) this;
+ }
+
+ /**
* <a href="http://camel.apache.org/content-based-router.html">Content
Based Router EIP:</a>
* Creates a choice of one or more predicates with an otherwise clause
*
Modified:
camel/trunk/camel-core/src/main/java/org/apache/camel/model/language/ExpressionDefinition.java
URL:
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/model/language/ExpressionDefinition.java?rev=892606&r1=892605&r2=892606&view=diff
==============================================================================
---
camel/trunk/camel-core/src/main/java/org/apache/camel/model/language/ExpressionDefinition.java
(original)
+++
camel/trunk/camel-core/src/main/java/org/apache/camel/model/language/ExpressionDefinition.java
Sun Dec 20 16:33:19 2009
@@ -54,7 +54,7 @@
@XmlJavaTypeAdapter(CollapsedStringAdapter.class)
@XmlID
private String id;
- @XmlValue
+ @XmlValue()
private String expression;
@XmlTransient
private Predicate predicate;
Added:
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/LogProcessor.java
URL:
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/processor/LogProcessor.java?rev=892606&view=auto
==============================================================================
---
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/LogProcessor.java
(added)
+++
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/LogProcessor.java
Sun Dec 20 16:33:19 2009
@@ -0,0 +1,51 @@
+/**
+ * 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.processor;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Expression;
+import org.apache.camel.Processor;
+
+/**
+ * A processor which evaluates an Expression and logs it.
+ *
+ * @version $Revision$
+ */
+public class LogProcessor implements Processor, Traceable {
+
+ private final Expression expression;
+ private final Logger logger;
+
+ public LogProcessor(Expression expression, Logger logger) {
+ this.expression = expression;
+ this.logger = logger;
+ }
+
+ public void process(Exchange exchange) throws Exception {
+ String msg = expression.evaluate(exchange, String.class);
+ logger.log(msg);
+ }
+
+ @Override
+ public String toString() {
+ return "Log[" + expression + "]";
+ }
+
+ public String getTraceLabel() {
+ return "log[" + expression + "]";
+ }
+}
Propchange:
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/LogProcessor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/LogProcessor.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Modified:
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/MarshalProcessor.java
URL:
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/processor/MarshalProcessor.java?rev=892606&r1=892605&r2=892606&view=diff
==============================================================================
---
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/MarshalProcessor.java
(original)
+++
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/MarshalProcessor.java
Sun Dec 20 16:33:19 2009
@@ -30,7 +30,7 @@
*
* @version $Revision$
*/
-public class MarshalProcessor implements Processor {
+public class MarshalProcessor implements Processor, Traceable {
private final DataFormat dataFormat;
public MarshalProcessor(DataFormat dataFormat) {
@@ -58,4 +58,8 @@
public String toString() {
return "Marshal[" + dataFormat + "]";
}
+
+ public String getTraceLabel() {
+ return "marshal[" + dataFormat + "]";
+ }
}
Modified:
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/UnmarshalProcessor.java
URL:
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/processor/UnmarshalProcessor.java?rev=892606&r1=892605&r2=892606&view=diff
==============================================================================
---
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/UnmarshalProcessor.java
(original)
+++
camel/trunk/camel-core/src/main/java/org/apache/camel/processor/UnmarshalProcessor.java
Sun Dec 20 16:33:19 2009
@@ -31,7 +31,7 @@
*
* @version $Revision$
*/
-public class UnmarshalProcessor implements Processor {
+public class UnmarshalProcessor implements Processor, Traceable {
private final DataFormat dataFormat;
public UnmarshalProcessor(DataFormat dataFormat) {
@@ -61,4 +61,7 @@
return "Unmarshal[" + dataFormat + "]";
}
+ public String getTraceLabel() {
+ return "unmarshal[" + dataFormat + "]";
+ }
}
\ No newline at end of file
Modified:
camel/trunk/camel-core/src/main/resources/org/apache/camel/model/jaxb.index
URL:
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/resources/org/apache/camel/model/jaxb.index?rev=892606&r1=892605&r2=892606&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/resources/org/apache/camel/model/jaxb.index
(original)
+++ camel/trunk/camel-core/src/main/resources/org/apache/camel/model/jaxb.index
Sun Dec 20 16:33:19 2009
@@ -36,6 +36,7 @@
InterceptSendToEndpointDefinition
LoadBalanceDefinition
LoadBalancerDefinition
+LogDefinition
LoopDefinition
MarshalDefinition
MulticastDefinition
Added:
camel/trunk/camel-core/src/test/java/org/apache/camel/processor/LogProcessorTest.java
URL:
http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/processor/LogProcessorTest.java?rev=892606&view=auto
==============================================================================
---
camel/trunk/camel-core/src/test/java/org/apache/camel/processor/LogProcessorTest.java
(added)
+++
camel/trunk/camel-core/src/test/java/org/apache/camel/processor/LogProcessorTest.java
Sun Dec 20 16:33:19 2009
@@ -0,0 +1,66 @@
+/**
+ * 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.processor;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.LoggingLevel;
+import org.apache.camel.builder.RouteBuilder;
+
+/**
+ * @version $Revision$
+ */
+public class LogProcessorTest extends ContextTestSupport {
+
+ public void testLogProcessorFoo() throws Exception {
+ getMockEndpoint("mock:foo").expectedMessageCount(1);
+
+ template.sendBody("direct:foo", "Hello World");
+
+ assertMockEndpointsSatisfied();
+ }
+
+ public void testLogProcessorBar() throws Exception {
+ getMockEndpoint("mock:bar").expectedMessageCount(1);
+
+ template.sendBody("direct:bar", "Bye World");
+
+ assertMockEndpointsSatisfied();
+ }
+
+ public void testLogProcessorBaz() throws Exception {
+ getMockEndpoint("mock:baz").expectedMessageCount(1);
+
+ template.sendBody("direct:baz", "Hi World");
+
+ assertMockEndpointsSatisfied();
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() throws Exception {
+ return new RouteBuilder() {
+ @Override
+ public void configure() throws Exception {
+ from("direct:foo").routeId("foo").log("Got
${body}").to("mock:foo");
+
+ from("direct:bar").routeId("bar").log(LoggingLevel.WARN, "Also
got ${body}").to("mock:bar");
+
+ from("direct:baz").routeId("baz").log(LoggingLevel.FATAL,
"cool", "Me got ${body}").to("mock:baz");
+ }
+ };
+ }
+
+}
Propchange:
camel/trunk/camel-core/src/test/java/org/apache/camel/processor/LogProcessorTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
camel/trunk/camel-core/src/test/java/org/apache/camel/processor/LogProcessorTest.java
------------------------------------------------------------------------------
svn:keywords = Rev Date
Copied:
camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringLogProcessorTest.java
(from r892586,
camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringConvertBodyTest.java)
URL:
http://svn.apache.org/viewvc/camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringLogProcessorTest.java?p2=camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringLogProcessorTest.java&p1=camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringConvertBodyTest.java&r1=892586&r2=892606&rev=892606&view=diff
==============================================================================
---
camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringConvertBodyTest.java
(original)
+++
camel/trunk/components/camel-spring/src/test/java/org/apache/camel/spring/processor/SpringLogProcessorTest.java
Sun Dec 20 16:33:19 2009
@@ -17,12 +17,14 @@
package org.apache.camel.spring.processor;
import org.apache.camel.CamelContext;
-import org.apache.camel.processor.ConvertBodyTest;
+import org.apache.camel.processor.LogProcessorTest;
+
import static
org.apache.camel.spring.processor.SpringTestHelper.createSpringCamelContext;
-public class SpringConvertBodyTest extends ConvertBodyTest {
+public class SpringLogProcessorTest extends LogProcessorTest {
+
protected CamelContext createCamelContext() throws Exception {
return createSpringCamelContext(this,
- "org/apache/camel/spring/processor/convertBody.xml");
+ "org/apache/camel/spring/processor/logProcessorTest.xml");
}
-}
+}
\ No newline at end of file
Copied:
camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/logProcessorTest.xml
(from r892586,
camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/convertBody.xml)
URL:
http://svn.apache.org/viewvc/camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/logProcessorTest.xml?p2=camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/logProcessorTest.xml&p1=camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/convertBody.xml&r1=892586&r2=892606&rev=892606&view=diff
==============================================================================
---
camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/convertBody.xml
(original)
+++
camel/trunk/components/camel-spring/src/test/resources/org/apache/camel/spring/processor/logProcessorTest.xml
Sun Dec 20 16:33:19 2009
@@ -22,49 +22,26 @@
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd
">
- <!-- START SNIPPET: example -->
- <camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
+ <camelContext id="camel" trace="true"
xmlns="http://camel.apache.org/schema/spring">
- <route>
- <from uri="direct:start"/>
- <convertBodyTo type="java.lang.Integer"/>
- <to uri="mock:result"/>
+ <route id="foo">
+ <from uri="direct:foo"/>
+ <log message="Got ${body}"/>
+ <to uri="mock:foo"/>
</route>
- <route errorHandlerRef="deadLetterErrorHandler">
- <from uri="direct:invalid"/>
- <convertBodyTo type="java.util.Date"/>
- <to uri="mock:result"/>
+ <route id="bar">
+ <from uri="direct:bar"/>
+ <log message="Also Got ${body}" loggingLevel="WARN"/>
+ <to uri="mock:bar"/>
</route>
- <route>
- <from uri="direct:charset"/>
- <convertBodyTo type="java.lang.byte[]" charset="iso-8859-1"/>
- <to uri="mock:result"/>
- </route>
-
- <route>
- <from uri="direct:charset2"/>
- <convertBodyTo type="java.lang.byte[]" charset="utf-16"/>
- <to uri="mock:result"/>
- </route>
-
- <route>
- <from uri="direct:charset3"/>
- <convertBodyTo type="java.lang.String" charset="utf-16"/>
- <to uri="mock:result"/>
+ <route id="baz">
+ <from uri="direct:baz"/>
+ <log message="Me Got ${body}" loggingLevel="FATAL" logName="cool"/>
+ <to uri="mock:baz"/>
</route>
</camelContext>
- <bean id="deadLetterErrorHandler"
class="org.apache.camel.builder.DeadLetterChannelBuilder">
- <property name="deadLetterUri" value="mock:dead"/>
- <property name="redeliveryPolicy" ref="redeliveryPolicy"/>
- <property name="handled" value="false"/>
- </bean>
-
- <bean id="redeliveryPolicy"
class="org.apache.camel.processor.RedeliveryPolicy">
- <property name="maximumRedeliveries" value="0"/>
- </bean>
- <!-- END SNIPPET: example -->
</beans>