文档章节

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

傲娇字符
 傲娇字符
发布于 2018/05/16 14:42
字数 663
阅读 84
收藏 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");
    }
}

© 著作权归作者所有

共有 人打赏支持
傲娇字符
粉丝 6
博文 43
码字总数 17111
作品 0
武汉
架构师
私信 提问
Apache Camel简介与入门

Apache Camel 是一个基于知名的企业应用模式(Enterprise Integration Patterns)多功能的整合框架. StackOverflow上有很多学习Apache Camel的资源,而这里仅仅是使用一个实例来简单的介绍一...

王振威
2012/09/23
45.8K
15
Apache Camel 2.11.4 发布

Camel 社区发布了新的补丁版本 camel-2.11.4,2月16日发布了 2.12.3 版本。此版本更新内容如下: Bug [CAMEL-6922] - XmlConverter cannot convert from ElementNSImpl to Document [CAMEL-6...

oschina
2014/02/26
1K
3
Apache Camel 2.6.0 发布

Apache Camel 是一个非常强大的基于规则的路由以及媒介引擎,该引擎提供了一个基于POJO的 企业应用模式(Enterprise Integration Patterns)的实现,你可以采用其异常强大且十分易用的API (可以...

红薯
2011/01/31
677
1
Apache Camel 2.15.5 发布,规则引擎

Apache Camel 2.15.5 发布,此版本更新内容如下: Bug 修复 [CAMEL-9161] - Camel spring-boot not finding routes when using spring-cloud [CAMEL-9202] - Flatpack: Body reader never c......

淡漠悠然
2015/12/01
1K
2
Apache Camel 2.18.0 发布,开源规则引擎

Apache Camel 2.18.0 发布了。 Apache Camel 是一个非常强大的基于规则的路由以及媒介引擎,该引擎提供了一个基于POJO的 企业应用模式(Enterprise Integration Patterns)的实现,你可以采用其...

达尔文
2016/10/11
1K
2

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周三乱弹 —— 风扇写着先生请自爱

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @蚂蚁哈哈哈 :分享陈奕迅的单曲《落花流水》 《落花流水》- 陈奕迅 手机党少年们想听歌,请使劲儿戳(这里) @车谷 :我发现每天上班都好困 ...

小小编辑
36分钟前
3
0
centos7重置密码、单用户模式、救援模式、ls命令、chmod命令

在工作当中如果我们错误的配置了文件使服务器不能正常启动或者忘记密码不能登录系统,如何解决这些问题呢?重装系统是可以实现的,但是往往不能轻易重装系统的,下面用忘记密码作为例子讲解如...

李超小牛子
今天
3
0
Python如何开发桌面应用程序?Python基础教程,第十三讲,图形界面

当使用桌面应用程序的时候,有没有那么一瞬间,想学习一下桌面应用程序开发?行业内专业的桌面应用程序开发一般是C++,C#来做,Java开发的也有,但是比较少。本节课会介绍Python的GUI(图形用...

程序员补给栈
今天
8
0
kafka在的使用

一、基本概念 介绍 Kafka是一个分布式的、可分区的、可复制的消息系统。它提供了普通消息系统的功能,但具有自己独特的设计。 这个独特的设计是什么样的呢? 首先让我们看几个基本的消息系统...

狼王黄师傅
今天
3
0
Android JNI总结

0x01 JNI介绍 JNI是Java Native Interface的缩写,JNI不是Android专有的东西,它是从Java继承而来,但是在Android中,JNI的作用和重要性大大增强。 JNI在Android中起着连接Java和C/C++层的作...

天王盖地虎626
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部