为 Apache Camel 配置数据源
Posted
技术标签:
【中文标题】为 Apache Camel 配置数据源【英文标题】:Configuring datasource for Apache Camel 【发布时间】:2018-11-16 20:50:53 【问题描述】:我在 application.properties 文件中定义了一个数据源:
spring.datasource.url = jdbc:mysql://localhost:3306/world?useSSL=false
spring.datasource.username = root
spring.datasource.password = password
但是,当我尝试运行我的 camelroute 时,我收到此错误:“在注册表中找不到 bean:类型的数据源:javax.sql.DataSource”。我总是在 spring 中使用 application.properties 文件配置我的数据源,没有问题。
完整的错误日志:
org.apache.camel.RuntimeCamelException: org.apache.camel.FailedToCreateRouteException: Failed to create route route5 at: >>> To[jdbc:datasource] <<< in route: Route(route5)[[From[bean:sqlBean?method=generateSqlQuery('ci... because of Failed to resolve endpoint: jdbc://datasource due to: No bean could be found in the registry for: datasource of type: javax.sql.DataSource
at org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException(ObjectHelper.java:1830) ~[camel-core-2.21.1.jar:2.21.1]
at org.apache.camel.spring.SpringCamelContext.start(SpringCamelContext.java:136) ~[camel-spring-2.21.1.jar:2.21.1]
at org.apache.camel.spring.SpringCamelContext.onApplicationEvent(SpringCamelContext.java:174) ~[camel-spring-2.21.1.jar:2.21.1]
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) ~[spring-context-4.3.17.RELEASE.jar:4.3.17.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) ~[spring-context-4.3.17.RELEASE.jar:4.3.17.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) ~[spring-context-4.3.17.RELEASE.jar:4.3.17.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:393) ~[spring-context-4.3.17.RELEASE.jar:4.3.17.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:347) ~[spring-context-4.3.17.RELEASE.jar:4.3.17.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:883) ~[spring-context-4.3.17.RELEASE.jar:4.3.17.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:144) ~[spring-boot-1.5.13.RELEASE.jar:1.5.13.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546) ~[spring-context-4.3.17.RELEASE.jar:4.3.17.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.13.RELEASE.jar:1.5.13.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) [spring-boot-1.5.13.RELEASE.jar:1.5.13.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) [spring-boot-1.5.13.RELEASE.jar:1.5.13.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) [spring-boot-1.5.13.RELEASE.jar:1.5.13.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.13.RELEASE.jar:1.5.13.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.13.RELEASE.jar:1.5.13.RELEASE]
at com.example.SpringApacheDemoApplication.main(SpringApacheDemoApplication.java:15) [classes/:na]
Caused by: org.apache.camel.FailedToCreateRouteException: Failed to create route route5 at: >>> To[jdbc:datasource] <<< in route: Route(route5)[[From[bean:sqlBean?method=generateSqlQuery('ci... because of Failed to resolve endpoint: jdbc://datasource due to: No bean could be found in the registry for: datasource of type: javax.sql.DataSource
at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:1303) ~[camel-core-2.21.1.jar:2.21.1]
at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:204) ~[camel-core-2.21.1.jar:2.21.1]
at org.apache.camel.impl.DefaultCamelContext.startRoute(DefaultCamelContext.java:1145) ~[camel-core-2.21.1.jar:2.21.1]
at org.apache.camel.impl.DefaultCamelContext.startRouteDefinitions(DefaultCamelContext.java:3731) ~[camel-core-2.21.1.jar:2.21.1]
at org.apache.camel.impl.DefaultCamelContext.doStartCamel(DefaultCamelContext.java:3445) ~[camel-core-2.21.1.jar:2.21.1]
at org.apache.camel.impl.DefaultCamelContext.access$000(DefaultCamelContext.java:209) ~[camel-core-2.21.1.jar:2.21.1]
at org.apache.camel.impl.DefaultCamelContext$2.call(DefaultCamelContext.java:3253) ~[camel-core-2.21.1.jar:2.21.1]
at org.apache.camel.impl.DefaultCamelContext$2.call(DefaultCamelContext.java:3249) ~[camel-core-2.21.1.jar:2.21.1]
at org.apache.camel.impl.DefaultCamelContext.doWithDefinedClassLoader(DefaultCamelContext.java:3272) ~[camel-core-2.21.1.jar:2.21.1]
at org.apache.camel.impl.DefaultCamelContext.doStart(DefaultCamelContext.java:3249) ~[camel-core-2.21.1.jar:2.21.1]
at org.apache.camel.support.ServiceSupport.start(ServiceSupport.java:61) ~[camel-core-2.21.1.jar:2.21.1]
at org.apache.camel.impl.DefaultCamelContext.start(DefaultCamelContext.java:3165) ~[camel-core-2.21.1.jar:2.21.1]
at org.apache.camel.spring.SpringCamelContext.start(SpringCamelContext.java:133) ~[camel-spring-2.21.1.jar:2.21.1]
... 16 common frames omitted
Caused by: org.apache.camel.ResolveEndpointFailedException: Failed to resolve endpoint: jdbc://datasource due to: No bean could be found in the registry for: datasource of type: javax.sql.DataSource
at org.apache.camel.impl.DefaultCamelContext.getEndpoint(DefaultCamelContext.java:758) ~[camel-core-2.21.1.jar:2.21.1]
at org.apache.camel.util.CamelContextHelper.getMandatoryEndpoint(CamelContextHelper.java:80) ~[camel-core-2.21.1.jar:2.21.1]
at org.apache.camel.model.RouteDefinition.resolveEndpoint(RouteDefinition.java:219) ~[camel-core-2.21.1.jar:2.21.1]
at org.apache.camel.impl.DefaultRouteContext.resolveEndpoint(DefaultRouteContext.java:115) ~[camel-core-2.21.1.jar:2.21.1]
at org.apache.camel.impl.DefaultRouteContext.resolveEndpoint(DefaultRouteContext.java:121) ~[camel-core-2.21.1.jar:2.21.1]
at org.apache.camel.model.SendDefinition.resolveEndpoint(SendDefinition.java:62) ~[camel-core-2.21.1.jar:2.21.1]
at org.apache.camel.model.SendDefinition.createProcessor(SendDefinition.java:56) ~[camel-core-2.21.1.jar:2.21.1]
at org.apache.camel.model.ProcessorDefinition.makeProcessorImpl(ProcessorDefinition.java:562) ~[camel-core-2.21.1.jar:2.21.1]
at org.apache.camel.model.ProcessorDefinition.makeProcessor(ProcessorDefinition.java:523) ~[camel-core-2.21.1.jar:2.21.1]
at org.apache.camel.model.ProcessorDefinition.addRoutes(ProcessorDefinition.java:239) ~[camel-core-2.21.1.jar:2.21.1]
at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:1300) ~[camel-core-2.21.1.jar:2.21.1]
... 28 common frames omitted
Caused by: org.apache.camel.NoSuchBeanException: No bean could be found in the registry for: datasource of type: javax.sql.DataSource
at org.apache.camel.util.CamelContextHelper.mandatoryLookup(CamelContextHelper.java:189) ~[camel-core-2.21.1.jar:2.21.1]
at org.apache.camel.component.jdbc.JdbcComponent.createEndpoint(JdbcComponent.java:52) ~[camel-jdbc-2.21.1.jar:2.21.1]
at org.apache.camel.impl.DefaultComponent.createEndpoint(DefaultComponent.java:126) ~[camel-core-2.21.1.jar:2.21.1]
at org.apache.camel.impl.DefaultCamelContext.getEndpoint(DefaultCamelContext.java:711) ~[camel-core-2.21.1.jar:2.21.1]
... 38 common frames omitted
我的骆驼路线:
from("bean:sqlBean?method=generateSqlQuery('tablename')")
.to("jdbc:datasource")
.process( new Processor ()
@Override
public void process(Exchange exchange) throws Exception
exchange.getOut().toString();
);
编辑:我像这样以编程方式添加了数据源:
@Bean
@Primary
public DataSource datasource()
System.out.println("hihihi");
return DataSourceBuilder
.create()
.username("root")
.password("password")
.url("jdbc:mysql://localhost:3306/world?useSSL=false")
.driverClassName("com.mysql.jdbc.Driver")
.build();
但是,现在我遇到了另一个错误:
Caused by: java.lang.UnsupportedOperationException: You cannot consume from a bean endpoint
at org.apache.camel.component.bean.BeanEndpoint.createConsumer(BeanEndpoint.java:75) ~[camel-core-2.21.1.jar:2.21.1]
at org.apache.camel.impl.EventDrivenConsumerRoute.addServices(EventDrivenConsumerRoute.java:69) ~[camel-core-2.21.1.jar:2.21.1]
at org.apache.camel.impl.DefaultRoute.onStartingServices(DefaultRoute.java:103) ~[camel-core-2.21.1.jar:2.21.1]
at org.apache.camel.impl.RouteService.doWarmUp(RouteService.java:172) ~[camel-core-2.21.1.jar:2.21.1]
at org.apache.camel.impl.RouteService.warmUp(RouteService.java:145) ~[camel-core-2.21.1.jar:2.21.1]
... 28 common frames omitted
【问题讨论】:
Configure DataSource programmatically in Spring Boot的可能重复 【参考方案1】:我想您正在使用 Spring Boot。也许“数据源”不是 Spring Boot 给出的名称?一个选项是检查 Spring Boot 加载的所有 bean 的名称。更多信息:Print all the Spring beans that are loaded - Spring Boot
另一个早期选项是以编程方式配置您的数据源并设置所需的名称。更多信息:Configure DataSource programmatically in Spring Boot
希望对你有帮助。
对于新的错误,你可以使用直接组件,例如:
from("direct:start")
.to("bean:sqlBean?method=generateSqlQuery('tablename')")
.to("jdbc:datasource")
.process( new Processor ()
@Override
public void process(Exchange exchange) throws Exception
exchange.getOut().toString();
);
【讨论】:
我也不同意投反对票。我提出了一个与此相关的问题,与后来 Makoto 提出的相同。 我遵循了你的建议,包括在控制台中打印 bean 名称的建议,现在我可以看到确实有一个名称为“datasource”的 bean,但我遇到了另一个错误, “不能从 bean 端点消费”。 感谢您的免责声明。错误是告诉您 bean 端点不能定义为路由的输入,例如,您应该使用 from 中的直接组件,然后调用您的 bean 端点。更多信息和示例在这里:camel.apache.org/bean.html【参考方案2】:由于您使用的是 Apache Camel,因此您需要像这样定义一个数据源 bean
<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="sqlComponent" class="org.apache.camel.component.sql.SqlComponent">
<property name="dataSource" ref="dataSource" />
</bean>
</beans>
您的 application.properties 文件应配置如下
spring.datasource.url=#use your url here
spring.datasource.username=TEST
spring.datasource.password=TEST
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver #give your own driver-class name
spring.datasource.testWhileIdle=true
spring.datasource.validationQuery=SELECT 1
spring.jpa.show-sql=true
【讨论】:
我可以知道投反对票的原因吗,因为我也在使用 Apache Camel 和 Spring Boot,并且配置方式相同,它对我有用 谢谢,没问题!尝试在@SpringBootApplication
注释下方添加 @EnableAutoConfiguration
【参考方案3】:
我来到这里是因为我正在研究一个类似的问题,我们正在将基于 xml 的骆驼代码迁移到 Springboot 和 Java 配置。通过执行以下操作,我能够自动配置数据源:
添加依赖spring-boot-starter-jdbc
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
版本取决于您使用的 Springboot 版本。
在您的 application.properties 文件中配置以下内容
spring.datasource.driver-class-name = <driverName>
spring.datasource.url = <url>
spring.datasource.username = <username>
spring.datasource.password = <password>
按照上述步骤,Springboot 将为您自动配置 dataSource bean。
这是我尝试运行存储过程的示例骆驼路线:
from("timer://mytimer?fixedRate=true&period=10s")
.log("TESTING")
.setBody(constant("EXEC SP_Manuals @DocumentRef = 'xyz1234' , @Year = '2019'"))
.to("jdbc:dataSource")
“dataSource”是 Springboot 创建的 DataSource bean。
如果你使用 to("jdbc:datasource") 你会得到下面的异常。
Caused by: org.apache.camel.NoSuchBeanException: No bean could be found in the registry for: datasource of type: javax.sql.DataSource
只是附加信息,如果忘记包含 camel-jdbc 依赖项,您将得到以下异常:
Caused by: org.apache.camel.ResolveEndpointFailedException: Failed to resolve endpoint: jdbc://dataSource due to: No component found with scheme: jdbc
所以请确保你的 pom.xml 中有 camel-jdbc 依赖项
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jdbc</artifactId>
</dependency>
【讨论】:
以上是关于为 Apache Camel 配置数据源的主要内容,如果未能解决你的问题,请参考以下文章
如何在apache camel DSL或camel Processor内部设置其他身份验证属性?