You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2018/03/28 18:45:41 UTC

[camel] 02/04: CAMEL-12285: Added mybatis-bean as component to use MyBatis annotation mapper.

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit d5eb9a7753dd201532de6130b40aaa8594377de9
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Wed Mar 28 19:25:17 2018 +0200

    CAMEL-12285: Added mybatis-bean as component to use MyBatis annotation mapper.
---
 ...BatisEndpoint.java => BaseMyBatisEndpoint.java} |  68 +--------
 .../component/mybatis/MyBatisBeanComponent.java    |  44 ++++++
 .../component/mybatis/MyBatisBeanEndpoint.java     |  80 +++++++++++
 .../component/mybatis/MyBatisBeanProducer.java     |  92 ++++++++++++
 .../camel/component/mybatis/MyBatisComponent.java  |   8 +-
 .../camel/component/mybatis/MyBatisEndpoint.java   | 156 +--------------------
 .../org/apache/camel/component/mybatis-bean        |  18 +++
 .../component/mybatis/bean/AccountService.java     |  35 +++++
 .../mybatis/bean/MyBatisBeanSelectListTest.java    |  57 ++++++++
 .../mybatis/bean/MyBatisBeanSelectOneTest.java     |  54 +++++++
 .../src/test/resources/SqlMapConfig.xml            |   2 +
 .../MyBatisBeanComponentAutoConfiguration.java     | 129 +++++++++++++++++
 .../MyBatisBeanComponentConfiguration.java         |  78 +++++++++++
 .../src/main/resources/META-INF/spring.factories   |   4 +-
 14 files changed, 602 insertions(+), 223 deletions(-)

diff --git a/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisEndpoint.java b/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/BaseMyBatisEndpoint.java
similarity index 73%
copy from components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisEndpoint.java
copy to components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/BaseMyBatisEndpoint.java
index a394ef2..77ae5de 100644
--- a/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisEndpoint.java
+++ b/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/BaseMyBatisEndpoint.java
@@ -5,9 +5,9 @@
  * 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
- *
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
  * 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.
@@ -19,28 +19,12 @@ package org.apache.camel.component.mybatis;
 import java.io.IOException;
 
 import org.apache.camel.Component;
-import org.apache.camel.Consumer;
-import org.apache.camel.Processor;
-import org.apache.camel.Producer;
 import org.apache.camel.impl.DefaultPollingEndpoint;
-import org.apache.camel.spi.Metadata;
-import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
-import org.apache.camel.spi.UriPath;
-import org.apache.camel.util.ObjectHelper;
 import org.apache.ibatis.session.ExecutorType;
 import org.apache.ibatis.session.SqlSessionFactory;
 
-/**
- * Performs a query, poll, insert, update or delete in a relational database using MyBatis.
- */
-@UriEndpoint(firstVersion = "2.7.0", scheme = "mybatis", title = "MyBatis", syntax = "mybatis:statement", consumerClass =  MyBatisConsumer.class, label = "database,sql")
-public class MyBatisEndpoint extends DefaultPollingEndpoint {
-
-    @UriPath @Metadata(required = "true")
-    private String statement;
-    @UriParam(label = "producer")
-    private StatementType statementType;
+public abstract class BaseMyBatisEndpoint extends DefaultPollingEndpoint {
     @UriParam(label = "consumer", description = "Enables or disables transaction. If enabled then if processing an exchange failed then the consumer"
             + "break out processing any further exchanges to cause a rollback eager.")
     private boolean transacted;
@@ -61,29 +45,11 @@ public class MyBatisEndpoint extends DefaultPollingEndpoint {
     @UriParam(label = "producer", defaultValue = "SIMPLE")
     private ExecutorType executorType;
 
-    public MyBatisEndpoint() {
+    public BaseMyBatisEndpoint() {
     }
 
-    public MyBatisEndpoint(String endpointUri, Component component, String statement) {
+    public BaseMyBatisEndpoint(String endpointUri, Component component) {
         super(endpointUri, component);
-        this.statement = statement;
-    }
-
-    public Producer createProducer() throws Exception {
-        ObjectHelper.notNull(statementType, "statementType", this);
-        ObjectHelper.notNull(statement, "statement", this);
-        return new MyBatisProducer(this);
-    }
-
-    public Consumer createConsumer(Processor processor) throws Exception {
-        ObjectHelper.notNull(statement, "statement", this);
-        MyBatisConsumer consumer = new MyBatisConsumer(this, processor);
-        consumer.setMaxMessagesPerPoll(getMaxMessagesPerPoll());
-        consumer.setOnConsume(getOnConsume());
-        consumer.setUseIterator(isUseIterator());
-        consumer.setRouteEmptyResultSet(isRouteEmptyResultSet());
-        configureConsumer(consumer);
-        return consumer;
     }
 
     public boolean isSingleton() {
@@ -99,28 +65,6 @@ public class MyBatisEndpoint extends DefaultPollingEndpoint {
         return getComponent().getSqlSessionFactory();
     }
 
-    public String getStatement() {
-        return statement;
-    }
-
-    /**
-     * The statement name in the MyBatis XML mapping file which maps to the query, insert, update or delete operation you wish to evaluate.
-     */
-    public void setStatement(String statement) {
-        this.statement = statement;
-    }
-
-    public StatementType getStatementType() {
-        return statementType;
-    }
-
-    /**
-     * Mandatory to specify for the producer to control which kind of operation to invoke.
-     */
-    public void setStatementType(StatementType statementType) {
-        this.statementType = statementType;
-    }
-
     public ExecutorType getExecutorType() {
         return executorType;
     }
diff --git a/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisBeanComponent.java b/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisBeanComponent.java
new file mode 100644
index 0000000..6a0b1a6
--- /dev/null
+++ b/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisBeanComponent.java
@@ -0,0 +1,44 @@
+/**
+ * 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.component.mybatis;
+
+import java.util.Map;
+
+import org.apache.camel.Endpoint;
+import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.StringHelper;
+
+public class MyBatisBeanComponent extends MyBatisComponent {
+
+    @Override
+    protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
+        String beanName = StringHelper.before(remaining, ":");
+        String methodName = StringHelper.after(remaining, ":");
+
+        if (ObjectHelper.isEmpty(beanName)) {
+            throw new IllegalArgumentException("The option beanName must be provided when creating endpoint: " + uri);
+        }
+        if (ObjectHelper.isEmpty(methodName)) {
+            throw new IllegalArgumentException("The option methodName must be provided when creating endpoint: " + uri);
+        }
+
+        MyBatisBeanEndpoint answer = new MyBatisBeanEndpoint(uri, this, beanName, methodName);
+        setProperties(answer, parameters);
+        return answer;
+    }
+
+}
diff --git a/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisBeanEndpoint.java b/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisBeanEndpoint.java
new file mode 100644
index 0000000..09a94cd6
--- /dev/null
+++ b/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisBeanEndpoint.java
@@ -0,0 +1,80 @@
+/**
+ * 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.component.mybatis;
+
+import org.apache.camel.Component;
+import org.apache.camel.Consumer;
+import org.apache.camel.Processor;
+import org.apache.camel.Producer;
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.UriEndpoint;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.UriPath;
+
+/**
+ * Performs a query, insert, update or delete in a relational database using MyBatis.
+ */
+@UriEndpoint(firstVersion = "2.22.0", scheme = "mybatis-bean", title = "MyBatis Bean", syntax = "mybatis-bean:beanName:methodName", producerOnly = true, label = "database,sql")
+public class MyBatisBeanEndpoint extends BaseMyBatisEndpoint {
+
+    @UriPath @Metadata(required = "true")
+    private String beanName;
+    @UriParam(label = "producer")
+    private String methodName;
+
+    public MyBatisBeanEndpoint() {
+    }
+
+    public MyBatisBeanEndpoint(String endpointUri, Component component, String beanName, String methodName) {
+        super(endpointUri, component);
+        this.beanName = beanName;
+        this.methodName = methodName;
+    }
+
+    public Producer createProducer() throws Exception {
+        return new MyBatisBeanProducer(this);
+    }
+
+    @Override
+    public Consumer createConsumer(Processor processor) throws Exception {
+        throw new IllegalArgumentException("Consumer not support on this component (mybatis-bean), use mybatis instead.");
+    }
+
+    public String getBeanName() {
+        return beanName;
+    }
+
+    /**
+     * Name of the bean with the MyBatis annotations.
+     * This can either by a type alias or a FQN class name.
+     */
+    public void setBeanName(String beanName) {
+        this.beanName = beanName;
+    }
+
+    public String getMethodName() {
+        return methodName;
+    }
+
+    /**
+     * Name of the method on the bean that has the SQL query to be executed.
+     */
+    public void setMethodName(String methodName) {
+        this.methodName = methodName;
+    }
+
+}
diff --git a/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisBeanProducer.java b/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisBeanProducer.java
new file mode 100644
index 0000000..31ca99c
--- /dev/null
+++ b/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisBeanProducer.java
@@ -0,0 +1,92 @@
+/**
+ * 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.component.mybatis;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.component.bean.BeanProcessor;
+import org.apache.camel.impl.DefaultProducer;
+import org.apache.camel.util.IOHelper;
+import org.apache.camel.util.ServiceHelper;
+import org.apache.ibatis.session.ExecutorType;
+import org.apache.ibatis.session.SqlSession;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MyBatisBeanProducer extends DefaultProducer {
+
+    private static final Logger LOG = LoggerFactory.getLogger(MyBatisBeanProducer.class);
+    private MyBatisBeanEndpoint endpoint;
+    private BeanProcessor beanProcessor;
+    private SqlSession session;
+
+    public MyBatisBeanProducer(MyBatisBeanEndpoint endpoint) {
+        super(endpoint);
+        this.endpoint = endpoint;
+    }
+
+    public void process(Exchange exchange) throws Exception {
+        LOG.trace("Invoking MyBatisBean on {}:{}", endpoint.getBeanName(), endpoint.getMethodName());
+        beanProcessor.process(exchange);
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        super.doStart();
+
+        // discover the bean and get the mapper
+        session = null;
+
+        ExecutorType executorType = endpoint.getExecutorType();
+        if (executorType == null) {
+            session = endpoint.getSqlSessionFactory().openSession();
+        } else {
+            session = endpoint.getSqlSessionFactory().openSession(executorType);
+        }
+        LOG.debug("Opened MyBatis SqlSession: {}", session);
+
+        // is the bean a alias type
+        Class clazz = session.getConfiguration().getTypeAliasRegistry().resolveAlias(endpoint.getBeanName());
+        if (clazz == null) {
+            // its maybe a FQN so try to use Camel to lookup the class
+            clazz = getEndpoint().getCamelContext().getClassResolver().resolveMandatoryClass(endpoint.getBeanName());
+        }
+
+        LOG.debug("Resolved MyBatis Bean: {} as class: {}", endpoint.getBeanName(), clazz);
+
+        // find the mapper
+        Object mapper = session.getMapper(clazz);
+        if (mapper == null) {
+            throw new IllegalArgumentException("No Mapper with typeAlias or class name: " + endpoint.getBeanName() + " in MyBatis configuration.");
+        }
+        LOG.debug("Resolved MyBatis Bean mapper: {}", mapper);
+
+        beanProcessor = new BeanProcessor(mapper, getEndpoint().getCamelContext());
+        beanProcessor.setMethod(endpoint.getMethodName());
+        ServiceHelper.startService(beanProcessor);
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        super.doStop();
+
+        ServiceHelper.stopService(beanProcessor);
+
+        LOG.debug("Closing MyBatis SqlSession: {}", session);
+        IOHelper.close(session);
+        session = null;
+    }
+}
diff --git a/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisComponent.java b/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisComponent.java
index 1635ea7..deb8d7a 100644
--- a/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisComponent.java
+++ b/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisComponent.java
@@ -21,7 +21,7 @@ import java.io.InputStream;
 import java.util.Map;
 
 import org.apache.camel.Endpoint;
-import org.apache.camel.impl.UriEndpointComponent;
+import org.apache.camel.impl.DefaultComponent;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.util.IOHelper;
 import org.apache.camel.util.ObjectHelper;
@@ -32,17 +32,13 @@ import org.apache.ibatis.session.SqlSessionFactoryBuilder;
 /**
  * @version 
  */
-public class MyBatisComponent extends UriEndpointComponent {
+public class MyBatisComponent extends DefaultComponent {
 
     @Metadata(label = "advanced")
     private SqlSessionFactory sqlSessionFactory;
     @Metadata(defaultValue = "SqlMapConfig.xml")
     private String configurationUri = "SqlMapConfig.xml";
 
-    public MyBatisComponent() {
-        super(MyBatisEndpoint.class);
-    }
-
     @Override
     protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
         MyBatisEndpoint answer = new MyBatisEndpoint(uri, this, remaining);
diff --git a/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisEndpoint.java b/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisEndpoint.java
index a394ef2..418c6e9 100644
--- a/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisEndpoint.java
+++ b/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisEndpoint.java
@@ -34,32 +34,13 @@ import org.apache.ibatis.session.SqlSessionFactory;
 /**
  * Performs a query, poll, insert, update or delete in a relational database using MyBatis.
  */
-@UriEndpoint(firstVersion = "2.7.0", scheme = "mybatis", title = "MyBatis", syntax = "mybatis:statement", consumerClass =  MyBatisConsumer.class, label = "database,sql")
-public class MyBatisEndpoint extends DefaultPollingEndpoint {
+@UriEndpoint(firstVersion = "2.7.0", scheme = "mybatis", title = "MyBatis", syntax = "mybatis:statement", consumerClass = MyBatisConsumer.class, label = "database,sql")
+public class MyBatisEndpoint extends BaseMyBatisEndpoint {
 
     @UriPath @Metadata(required = "true")
     private String statement;
     @UriParam(label = "producer")
     private StatementType statementType;
-    @UriParam(label = "consumer", description = "Enables or disables transaction. If enabled then if processing an exchange failed then the consumer"
-            + "break out processing any further exchanges to cause a rollback eager.")
-    private boolean transacted;
-    @UriParam(label = "consumer", defaultValue = "0")
-    private int maxMessagesPerPoll;
-    @UriParam
-    private String outputHeader;
-    @UriParam(label = "consumer")
-    private String inputHeader;
-    @UriParam(label = "consumer", optionalPrefix = "consumer.")
-    private String onConsume;
-    @UriParam(label = "consumer", optionalPrefix = "consumer.", defaultValue = "true")
-    private boolean useIterator = true;
-    @UriParam(label = "consumer", optionalPrefix = "consumer.")
-    private boolean routeEmptyResultSet;
-    @UriParam(label = "consumer,advanced")
-    private MyBatisProcessingStrategy processingStrategy = new DefaultMyBatisProcessingStrategy();
-    @UriParam(label = "producer", defaultValue = "SIMPLE")
-    private ExecutorType executorType;
 
     public MyBatisEndpoint() {
     }
@@ -86,19 +67,6 @@ public class MyBatisEndpoint extends DefaultPollingEndpoint {
         return consumer;
     }
 
-    public boolean isSingleton() {
-        return true;
-    }
-
-    @Override
-    public MyBatisComponent getComponent() {
-        return (MyBatisComponent) super.getComponent();
-    }
-
-    public SqlSessionFactory getSqlSessionFactory() throws IOException {
-        return getComponent().getSqlSessionFactory();
-    }
-
     public String getStatement() {
         return statement;
     }
@@ -121,124 +89,4 @@ public class MyBatisEndpoint extends DefaultPollingEndpoint {
         this.statementType = statementType;
     }
 
-    public ExecutorType getExecutorType() {
-        return executorType;
-    }
-
-    /**
-     * The executor type to be used while executing statements.
-     * <ul>
-     *     <li>simple - executor does nothing special.</li>
-     *     <li>reuse - executor reuses prepared statements.</li>
-     *     <li>batch - executor reuses statements and batches updates.</li>
-     * </ul>
-     */
-    public void setExecutorType(ExecutorType executorType) {
-        this.executorType = executorType;
-    }
-
-    public void setExecutorType(String executorType) {
-        this.executorType = ExecutorType.valueOf(executorType.toUpperCase());
-    }
-
-    public boolean isTransacted() {
-        return transacted;
-    }
-
-    /**
-     * Enables or disables transaction. If enabled then if processing an exchange failed then the consumer
-     + break out processing any further exchanges to cause a rollback eager
-     */
-    public void setTransacted(boolean transacted) {
-        this.transacted = transacted;
-    }
-
-    public MyBatisProcessingStrategy getProcessingStrategy() {
-        return processingStrategy;
-    }
-
-    /**
-     * To use a custom MyBatisProcessingStrategy
-     */
-    public void setProcessingStrategy(MyBatisProcessingStrategy processingStrategy) {
-        this.processingStrategy = processingStrategy;
-    }
-
-    public int getMaxMessagesPerPoll() {
-        return maxMessagesPerPoll;
-    }
-
-    /**
-     * This option is intended to split results returned by the database pool into the batches and deliver them in multiple exchanges.
-     * This integer defines the maximum messages to deliver in single exchange. By default, no maximum is set.
-     * Can be used to set a limit of e.g. 1000 to avoid when starting up the server that there are thousands of files.
-     * Set a value of 0 or negative to disable it.
-     */
-    public void setMaxMessagesPerPoll(int maxMessagesPerPoll) {
-        this.maxMessagesPerPoll = maxMessagesPerPoll;
-    }
-
-    public String getOutputHeader() {
-        return outputHeader;
-    }
-
-    /**
-     * Store the query result in a header instead of the message body.
-     * By default, outputHeader == null and the query result is stored in the message body,
-     * any existing content in the message body is discarded.
-     * If outputHeader is set, the value is used as the name of the header to store the
-     * query result and the original message body is preserved. Setting outputHeader will
-     * also omit populating the default CamelMyBatisResult header since it would be the same
-     * as outputHeader all the time.
-     */
-    public void setOutputHeader(String outputHeader) {
-        this.outputHeader = outputHeader;
-    }
-
-    public String getInputHeader() {
-        return inputHeader;
-    }
-
-    /**
-     * User the header value for input parameters instead of the message body.
-     * By default, inputHeader == null and the input parameters are taken from the message body.
-     * If outputHeader is set, the value is used and query parameters will be taken from the
-     * header instead of the body.
-     */
-    public void setInputHeader(String inputHeader) {
-        this.inputHeader = inputHeader;
-    }
-
-    public String getOnConsume() {
-        return onConsume;
-    }
-
-    /**
-     * Statement to run after data has been processed in the route
-     */
-    public void setOnConsume(String onConsume) {
-        this.onConsume = onConsume;
-    }
-
-    public boolean isUseIterator() {
-        return useIterator;
-    }
-
-    /**
-     * Process resultset individually or as a list
-     */
-    public void setUseIterator(boolean useIterator) {
-        this.useIterator = useIterator;
-    }
-
-    public boolean isRouteEmptyResultSet() {
-        return routeEmptyResultSet;
-    }
-
-    /**
-     * Whether allow empty resultset to be routed to the next hop
-     */
-    public void setRouteEmptyResultSet(boolean routeEmptyResultSet) {
-        this.routeEmptyResultSet = routeEmptyResultSet;
-    }
 }
diff --git a/components/camel-mybatis/src/main/resources/META-INF/services/org/apache/camel/component/mybatis-bean b/components/camel-mybatis/src/main/resources/META-INF/services/org/apache/camel/component/mybatis-bean
new file mode 100644
index 0000000..f9da46f
--- /dev/null
+++ b/components/camel-mybatis/src/main/resources/META-INF/services/org/apache/camel/component/mybatis-bean
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+class=org.apache.camel.component.mybatis.MyBatisBeanComponent
diff --git a/components/camel-mybatis/src/test/java/org/apache/camel/component/mybatis/bean/AccountService.java b/components/camel-mybatis/src/test/java/org/apache/camel/component/mybatis/bean/AccountService.java
new file mode 100644
index 0000000..ec3320a
--- /dev/null
+++ b/components/camel-mybatis/src/test/java/org/apache/camel/component/mybatis/bean/AccountService.java
@@ -0,0 +1,35 @@
+/**
+ * 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.component.mybatis.bean;
+
+import java.util.List;
+
+import org.apache.camel.component.mybatis.Account;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.ResultMap;
+import org.apache.ibatis.annotations.Select;
+
+public interface AccountService {
+
+    @Select("select ACC_ID as id, ACC_FIRST_NAME as firstName, ACC_LAST_NAME as lastName"
+        + ", ACC_EMAIL as emailAddress from ACCOUNT where ACC_ID = #{id}")
+    Account selectBeanAccountById(@Param("id") int no);
+
+    @Select("select * from ACCOUNT order by ACC_ID")
+    @ResultMap("Account.AccountResult")
+    List<Account> selectBeanAllAccounts();
+}
diff --git a/components/camel-mybatis/src/test/java/org/apache/camel/component/mybatis/bean/MyBatisBeanSelectListTest.java b/components/camel-mybatis/src/test/java/org/apache/camel/component/mybatis/bean/MyBatisBeanSelectListTest.java
new file mode 100644
index 0000000..72cbe1a
--- /dev/null
+++ b/components/camel-mybatis/src/test/java/org/apache/camel/component/mybatis/bean/MyBatisBeanSelectListTest.java
@@ -0,0 +1,57 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.component.mybatis.bean;
+
+import java.util.List;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.component.mybatis.Account;
+import org.apache.camel.component.mybatis.MyBatisTestSupport;
+import org.junit.Test;
+
+public class MyBatisBeanSelectListTest extends MyBatisTestSupport {
+
+    @Test
+    public void testSelectList() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(1);
+
+        template.sendBody("direct:start", null);
+
+        assertMockEndpointsSatisfied();
+
+        List<?> list = mock.getReceivedExchanges().get(0).getIn().getBody(List.class);
+        Account james = (Account) list.get(0);
+        Account claus = (Account) list.get(1);
+        assertEquals("James", james.getFirstName());
+        assertEquals("Claus", claus.getFirstName());
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start")
+                    .to("mybatis-bean:AccountService:selectBeanAllAccounts")
+                    .to("mock:result");
+            }
+        };
+    }
+
+}
diff --git a/components/camel-mybatis/src/test/java/org/apache/camel/component/mybatis/bean/MyBatisBeanSelectOneTest.java b/components/camel-mybatis/src/test/java/org/apache/camel/component/mybatis/bean/MyBatisBeanSelectOneTest.java
new file mode 100644
index 0000000..bdb4025
--- /dev/null
+++ b/components/camel-mybatis/src/test/java/org/apache/camel/component/mybatis/bean/MyBatisBeanSelectOneTest.java
@@ -0,0 +1,54 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.component.mybatis.bean;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.component.mybatis.Account;
+import org.apache.camel.component.mybatis.MyBatisTestSupport;
+import org.junit.Test;
+
+public class MyBatisBeanSelectOneTest extends MyBatisTestSupport {
+
+    @Test
+    public void testSelectOne() throws Exception {
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(1);
+        mock.message(0).body().isInstanceOf(Account.class);
+
+        template.sendBody("direct:start", 456);
+
+        assertMockEndpointsSatisfied();
+
+        Account account = mock.getReceivedExchanges().get(0).getIn().getBody(Account.class);
+        assertEquals("Claus", account.getFirstName());
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start")
+                    .to("mybatis-bean:AccountService:selectBeanAccountById")
+                    .to("mock:result");
+            }
+        };
+    }
+
+
+}
diff --git a/components/camel-mybatis/src/test/resources/SqlMapConfig.xml b/components/camel-mybatis/src/test/resources/SqlMapConfig.xml
index 4bc93c3..9347c08 100644
--- a/components/camel-mybatis/src/test/resources/SqlMapConfig.xml
+++ b/components/camel-mybatis/src/test/resources/SqlMapConfig.xml
@@ -30,6 +30,7 @@
     <!-- Use type aliases to avoid typing the full classname every time. -->
     <typeAliases>
         <typeAlias alias="Account" type="org.apache.camel.component.mybatis.Account"/>
+        <typeAlias alias="AccountService" type="org.apache.camel.component.mybatis.bean.AccountService"/>
     </typeAliases>
 
     <!-- setup environment with JDBC data source -->
@@ -46,6 +47,7 @@
     <!-- mapping files -->
     <mappers>
         <mapper resource="org/apache/camel/component/mybatis/Account.xml"/>
+        <package name="org.apache.camel.component.mybatis.bean"/>
     </mappers>
 
 </configuration>
\ No newline at end of file
diff --git a/platforms/spring-boot/components-starter/camel-mybatis-starter/src/main/java/org/apache/camel/component/mybatis/springboot/MyBatisBeanComponentAutoConfiguration.java b/platforms/spring-boot/components-starter/camel-mybatis-starter/src/main/java/org/apache/camel/component/mybatis/springboot/MyBatisBeanComponentAutoConfiguration.java
new file mode 100644
index 0000000..ea67c21
--- /dev/null
+++ b/platforms/spring-boot/components-starter/camel-mybatis-starter/src/main/java/org/apache/camel/component/mybatis/springboot/MyBatisBeanComponentAutoConfiguration.java
@@ -0,0 +1,129 @@
+/**
+ * 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.component.mybatis.springboot;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.Generated;
+import org.apache.camel.CamelContext;
+import org.apache.camel.component.mybatis.MyBatisBeanComponent;
+import org.apache.camel.spi.ComponentCustomizer;
+import org.apache.camel.spi.HasId;
+import org.apache.camel.spring.boot.CamelAutoConfiguration;
+import org.apache.camel.spring.boot.ComponentConfigurationProperties;
+import org.apache.camel.spring.boot.util.CamelPropertiesHelper;
+import org.apache.camel.spring.boot.util.ConditionalOnCamelContextAndAutoConfigurationBeans;
+import org.apache.camel.spring.boot.util.GroupCondition;
+import org.apache.camel.spring.boot.util.HierarchicalPropertiesEvaluator;
+import org.apache.camel.util.IntrospectionSupport;
+import org.apache.camel.util.ObjectHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Conditional;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Lazy;
+
+/**
+ * Generated by camel-package-maven-plugin - do not edit this file!
+ */
+@Generated("org.apache.camel.maven.packaging.SpringBootAutoConfigurationMojo")
+@Configuration
+@Conditional({ConditionalOnCamelContextAndAutoConfigurationBeans.class,
+        MyBatisBeanComponentAutoConfiguration.GroupConditions.class})
+@AutoConfigureAfter(CamelAutoConfiguration.class)
+@EnableConfigurationProperties({ComponentConfigurationProperties.class,
+        MyBatisBeanComponentConfiguration.class})
+public class MyBatisBeanComponentAutoConfiguration {
+
+    private static final Logger LOGGER = LoggerFactory
+            .getLogger(MyBatisBeanComponentAutoConfiguration.class);
+    @Autowired
+    private ApplicationContext applicationContext;
+    @Autowired
+    private CamelContext camelContext;
+    @Autowired
+    private MyBatisBeanComponentConfiguration configuration;
+    @Autowired(required = false)
+    private List<ComponentCustomizer<MyBatisBeanComponent>> customizers;
+
+    static class GroupConditions extends GroupCondition {
+        public GroupConditions() {
+            super("camel.component", "camel.component.mybatis-bean");
+        }
+    }
+
+    @Lazy
+    @Bean(name = "mybatis-bean-component")
+    @ConditionalOnMissingBean(MyBatisBeanComponent.class)
+    public MyBatisBeanComponent configureMyBatisBeanComponent()
+            throws Exception {
+        MyBatisBeanComponent component = new MyBatisBeanComponent();
+        component.setCamelContext(camelContext);
+        Map<String, Object> parameters = new HashMap<>();
+        IntrospectionSupport.getProperties(configuration, parameters, null,
+                false);
+        for (Map.Entry<String, Object> entry : parameters.entrySet()) {
+            Object value = entry.getValue();
+            Class<?> paramClass = value.getClass();
+            if (paramClass.getName().endsWith("NestedConfiguration")) {
+                Class nestedClass = null;
+                try {
+                    nestedClass = (Class) paramClass.getDeclaredField(
+                            "CAMEL_NESTED_CLASS").get(null);
+                    HashMap<String, Object> nestedParameters = new HashMap<>();
+                    IntrospectionSupport.getProperties(value, nestedParameters,
+                            null, false);
+                    Object nestedProperty = nestedClass.newInstance();
+                    CamelPropertiesHelper.setCamelProperties(camelContext,
+                            nestedProperty, nestedParameters, false);
+                    entry.setValue(nestedProperty);
+                } catch (NoSuchFieldException e) {
+                }
+            }
+        }
+        CamelPropertiesHelper.setCamelProperties(camelContext, component,
+                parameters, false);
+        if (ObjectHelper.isNotEmpty(customizers)) {
+            for (ComponentCustomizer<MyBatisBeanComponent> customizer : customizers) {
+                boolean useCustomizer = (customizer instanceof HasId)
+                        ? HierarchicalPropertiesEvaluator.evaluate(
+                                applicationContext.getEnvironment(),
+                                "camel.component.customizer",
+                                "camel.component.mybatis-bean.customizer",
+                                ((HasId) customizer).getId())
+                        : HierarchicalPropertiesEvaluator.evaluate(
+                                applicationContext.getEnvironment(),
+                                "camel.component.customizer",
+                                "camel.component.mybatis-bean.customizer");
+                if (useCustomizer) {
+                    LOGGER.debug("Configure component {}, with customizer {}",
+                            component, customizer);
+                    customizer.customize(component);
+                }
+            }
+        }
+        return component;
+    }
+}
\ No newline at end of file
diff --git a/platforms/spring-boot/components-starter/camel-mybatis-starter/src/main/java/org/apache/camel/component/mybatis/springboot/MyBatisBeanComponentConfiguration.java b/platforms/spring-boot/components-starter/camel-mybatis-starter/src/main/java/org/apache/camel/component/mybatis/springboot/MyBatisBeanComponentConfiguration.java
new file mode 100644
index 0000000..35025db
--- /dev/null
+++ b/platforms/spring-boot/components-starter/camel-mybatis-starter/src/main/java/org/apache/camel/component/mybatis/springboot/MyBatisBeanComponentConfiguration.java
@@ -0,0 +1,78 @@
+/**
+ * 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.component.mybatis.springboot;
+
+import javax.annotation.Generated;
+import org.apache.camel.spring.boot.ComponentConfigurationPropertiesCommon;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.NestedConfigurationProperty;
+
+/**
+ * Performs a query, insert, update or delete in a relational database using
+ * MyBatis.
+ * 
+ * Generated by camel-package-maven-plugin - do not edit this file!
+ */
+@Generated("org.apache.camel.maven.packaging.SpringBootAutoConfigurationMojo")
+@ConfigurationProperties(prefix = "camel.component.mybatis-bean")
+public class MyBatisBeanComponentConfiguration
+        extends
+            ComponentConfigurationPropertiesCommon {
+
+    /**
+     * To use the SqlSessionFactory
+     */
+    @NestedConfigurationProperty
+    private SqlSessionFactory sqlSessionFactory;
+    /**
+     * Location of MyBatis xml configuration file. The default value is:
+     * SqlMapConfig.xml loaded from the classpath
+     */
+    private String configurationUri = "SqlMapConfig.xml";
+    /**
+     * Whether the component should resolve property placeholders on itself when
+     * starting. Only properties which are of String type can use property
+     * placeholders.
+     */
+    private Boolean resolvePropertyPlaceholders = true;
+
+    public SqlSessionFactory getSqlSessionFactory() {
+        return sqlSessionFactory;
+    }
+
+    public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
+        this.sqlSessionFactory = sqlSessionFactory;
+    }
+
+    public String getConfigurationUri() {
+        return configurationUri;
+    }
+
+    public void setConfigurationUri(String configurationUri) {
+        this.configurationUri = configurationUri;
+    }
+
+    public Boolean getResolvePropertyPlaceholders() {
+        return resolvePropertyPlaceholders;
+    }
+
+    public void setResolvePropertyPlaceholders(
+            Boolean resolvePropertyPlaceholders) {
+        this.resolvePropertyPlaceholders = resolvePropertyPlaceholders;
+    }
+}
\ No newline at end of file
diff --git a/platforms/spring-boot/components-starter/camel-mybatis-starter/src/main/resources/META-INF/spring.factories b/platforms/spring-boot/components-starter/camel-mybatis-starter/src/main/resources/META-INF/spring.factories
index 63c8b50..8a07a35 100644
--- a/platforms/spring-boot/components-starter/camel-mybatis-starter/src/main/resources/META-INF/spring.factories
+++ b/platforms/spring-boot/components-starter/camel-mybatis-starter/src/main/resources/META-INF/spring.factories
@@ -15,4 +15,6 @@
 ## limitations under the License.
 ## ---------------------------------------------------------------------------
 org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-org.apache.camel.component.mybatis.springboot.MyBatisComponentAutoConfiguration
+org.apache.camel.component.mybatis.springboot.MyBatisComponentAutoConfiguration,\
+org.apache.camel.component.mybatis.springboot.MyBatisBeanComponentAutoConfiguration
+

-- 
To stop receiving notification emails like this one, please contact
davsclaus@apache.org.