文档章节

Apache Camel加载路由源码(扫描包路径方式)分析及注意事项

傲娇字符
 傲娇字符
发布于 05/16 14:42
字数 663
阅读 35
收藏 0

1.添加依赖包

gradle依赖:

compile 'org.apache.camel:camel-spring:2.20.3'

2.添加Spring配置信息

spring-camel.xml

<?xml version="1.0" encoding="UTF-8"?>

<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">

    <camelContext xmlns="http://camel.apache.org/schema/spring">
        <packageScan>
            <package>com.chz.apps.esb.camel.routes</package>
            <excludes>**.*Excluded*</excludes>
            <includes>**.*</includes>
        </packageScan>
    </camelContext>
</beans>

com.chz.apps.esb.camel.routes包是用于存放camel的路由类

3.编写路由类(错误的类)

此处使用本地文件往ftp自动上传文件为例:

package com.chz.apps.esb.camel.routes;

import org.apache.camel.builder.RouteBuilder;
import org.springframework.stereotype.Component;

/**
 * 本地文件往服务器自动同步机制
 */
@Component
public class FileTransFtpRouteBuilder extends RouteBuilder {

    @Override
    public void configure() {
        from("file:D:\\tmp\\camel")
        .to("ftp:ftpUsername:ftpPassword@192.168.9.175");
    }
}

4.问题描述

上面的builder是参考《Apache Camel Developer's Cookbook》第23页实例编写。每次启动的时候,会发现创建的route并没有添加到Camel的CamelContext中,也就是说路由并没有生效。

经过源码分析,Apache Camel在于Spring进行集成的时候,使用CamelContextFactoryBean进行相关Bean实例的统一管理。而使用packageScan进行启动时,需要调用如下方法:

@Override
    protected void findRouteBuildersByPackageScan(String[] packages, PackageScanFilter filter, List<RoutesBuilder> builders) throws Exception {
        // add filter to class resolver which then will filter
        getContext().getPackageScanClassResolver().addFilter(filter);

        PackageScanRouteBuilderFinder finder = new PackageScanRouteBuilderFinder(getContext(), packages, getContextClassLoaderOnStart(),
                                                                                 getBeanPostProcessor(), getContext().getPackageScanClassResolver());
        finder.appendBuilders(builders);

        // and remove the filter
        getContext().getPackageScanClassResolver().removeFilter(filter);
    }

finder.appendBuilders(builders);此方法用于扫描包路径下面所有类,如果不是Spring的bean,则使用路由初始化方法,加载到Camel容器中。而书中提到使用Component注解后,会导致此处自动过滤掉:

在dubug的时候,日志如下:

[MI TCP Connection(3)-127.0.0.1] efaultPackageScanClassResolver DEBUG Searching for implementations of org.apache.camel.RoutesBuilder in packages: [com.chz.apps.esb.camel.routes]
[MI TCP Connection(3)-127.0.0.1] efaultPackageScanClassResolver DEBUG Found: [class com.chz.apps.esb.camel.routes.FileTransFtpRouteBuilder]
[MI TCP Connection(3)-127.0.0.1] DefaultListableBeanFactory     DEBUG Returning cached instance of singleton bean 'fileTransFtpRouteBuilder'
[MI TCP Connection(3)-127.0.0.1] PackageScanRouteBuilderFinder  DEBUG Ignoring RouteBuilder class: class com.chz.apps.esb.camel.routes.FileTransFtpRouteBuilder

通过分析源码(PackageScanRouteBuilderFinder.shouldIgnoreBean方法),只要是Spring已经加载的bean,此处不会做任何处理。所以正确的方式应该是去掉Component注解。

/**
     * Appends all the {@link org.apache.camel.builder.RouteBuilder} instances that can be found on the classpath
     */
    public void appendBuilders(List<RoutesBuilder> list) throws IllegalAccessException, InstantiationException {
        Set<Class<?>> classes = resolver.findImplementations(RoutesBuilder.class, packages);
        for (Class<?> aClass : classes) {
            LOG.trace("Found RouteBuilder class: {}", aClass);

            // certain beans should be ignored
            if (shouldIgnoreBean(aClass)) {
                LOG.debug("Ignoring RouteBuilder class: {}", aClass);
                continue;
            }

            if (!isValidClass(aClass)) {
                LOG.debug("Ignoring invalid RouteBuilder class: {}", aClass);
                continue;
            }

            // type is valid so create and instantiate the builder
            @SuppressWarnings("unchecked")
            RoutesBuilder builder = instantiateBuilder((Class<? extends RoutesBuilder>) aClass);
            if (beanPostProcessor != null) {
                // Inject the annotated resource
                beanPostProcessor.postProcessBeforeInitialization(builder, builder.toString());
            }
            LOG.debug("Adding instantiated RouteBuilder: {}", builder);
            list.add(builder);
        }
    }

 protected boolean shouldIgnoreBean(Class<?> type) {
        Map<String, ?> beans = applicationContext.getBeansOfType(type, true, true);
        if (beans == null || beans.isEmpty()) {
            return false;
        }
        return true;
    }

5.编写路由类(正确的类)

package com.chz.apps.esb.camel.routes;

import org.apache.camel.builder.RouteBuilder;

/**
 * 本地文件往服务器自动同步机制
 */
public class FileTransFtpRouteBuilder extends RouteBuilder {

    @Override
    public void configure() {
        from("file:D:\\tmp\\camel")
        .to("ftp:ftpUsername:ftpPassword@192.168.9.175");
    }
}

© 著作权归作者所有

共有 人打赏支持
傲娇字符
粉丝 5
博文 38
码字总数 14769
作品 0
武汉
架构师
Camel概念【Architecture ①】

1.4 Camel’s architecture Let’s now turn our attention to Camel’s architecture. We’ll first take a look at the high-level architecture and then drill down into the specific c......

k_k_anna
2015/01/28
0
0
Camel概念【Camel’s message model(消息体模型)】

Camel’s message model In Camel, there are two abstractions for modeling messages, both of which we’ll cover in this section.(Camel中有两个抽象的消息体模型) org.apache.camel......

k_k_anna
2015/01/27
0
0
Camel概念【Exchange 】

Exchange An exchange in Camel is the message’s container during routing. (在camel中,exchange被当做路由交换的容器) An exchange also provides support for the various types of......

k_k_anna
2015/01/27
0
0
Camel In Action 读书笔记 (8)

第8章Enterprise integration patterns是core Camel的最后一章了,第二章已经介绍了一部分camel在eip中的应用。这一章全部都是讲eip. 看来eip确实是camel的核心,camel确实是基于eip的。 这一...

vidy_tu
2013/06/16
0
7
Camel-Core 分析 (1)

在Camel中定义一个路由最基本的元素有Context,Component,endPoint 。 在下图中可以看到Camel的顶层接口为Service. Camel的组件(比如Route,Component,Component,Endpoint,)都是以服务的形式...

vidy_tu
2013/06/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

windows nvm 安装 node

nvm 是 node 的版本控制管理 下面是下载 nvm 的地址,选择 nvm-setup.zip 下载 https://github.com/coreybutler/nvm-windows/releases 就是下一步下一步,一键安装 基本命令有: nvm arch [32...

U_I_A_N
9分钟前
0
0
函数式组件完整例子

之前创建的组件是比较简单,没有管理或者监听任何传递给他的状态,也没有生命周期方法。它只是一个接收参数的函数。 在下面这个例子中,我们标记组件为 functional,这意味它是无状态 (没有响...

tianyawhl
24分钟前
0
0
linux shell大文件操作

查找字符串所在行 : grep -n “待查找字符串” “文件名” 显示指定行信息:sed -n 1p “指定文件” 表示显示指定文件第一行的信息 ----------------------------------------------------...

悲催的古灵武士
25分钟前
0
0
centos7安装nexus3

centos7安装nexus3 2018年05月24日 16:20:34 阅读数:257 1、下载nexus wget https://sonatype-download.global.ssl.fastly.net/repository/repositoryManager/3/nexus-3.12.0-01-unix.tar.......

linjin200
26分钟前
1
0
springboot整合cxf发布webservice以及调用

webservice性能不高,但是现在好多公司还是在用,恰好今天在开发的时候对接项目组需要使用到webservice下面来说下简单的案例应用 首先老规矩:引入jar包 <dependency><groupId>org.apach...

落叶清风
30分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部