贝利信息

整合Spring XML上下文与Apache Camel 3.x实现长时运行应用

日期:2025-10-11 00:00 / 作者:心靈之曲

当迁移Apache Camel应用程序从2.x到3.x时,特别是那些利用Spring XML进行配置并需要持续运行的场景,`Main`类的使用方式会带来挑战。本文旨在解决如何正确运行一个集成Spring XML上下文的持久化Camel 3.x应用程序,重点阐述了`org.apache.camel.main.Main`与更适合此类场景的`org.apache.camel.spring.Main`(来自`camel-spring-main`构件)之间的关键区别。

1. 迁移挑战:Camel 2.x 到 3.x 的 Main 类与 Spring XML 集成

在Apache Camel 2.x版本中,开发者通常使用 org.apache.camel.spring.Main 类来启动一个长时运行的Camel应用程序,并同时加载Spring XML配置文件以管理Bean和配置。这种方式使得Camel路由能够无缝地利用Spring容器中定义的各种服务和属性。典型的启动代码示例如下:

package com.foo.email.ffdb.listener;

import java.util.Properties;
import javax.annotation.Resource;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.spring.Main; // Camel 2.x 使用的 Main 类
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.

annotation.Autowired; // ... 其他导入 public class EmailDBListener extends RouteBuilder { private static Logger log = LogManager.getLogger(EmailDBListener.class.getName()); private static String routeId = "EMAIL_ROUTE_ID"; // 简化常量 @Autowired private EmailDBProcessor emaiDBProcessor; @Resource private Properties emailProperties; public static void main(String[] args) throws Exception { System.out.println("STARTING EMAILDBLISTENER"); log.debug("Starting Email Batch "); Main main = new Main(); main.setApplicationContextUri("app-context.xml"); // 加载Spring XML上下文 main.run(); // 启动并保持运行 log.info("Email Batch Started:"); // 这行代码通常在 main.run() 阻塞后不会立即执行 } @Override public void configure() throws Exception { log.debug("configure() "); from(configureSqlTimer()) .routeId(routeId) .to("sqlComponent:{{SQL.READ_EMAIL_REQUESTS}}") .bean("fireForgetServiceMapper", "readEmailRequests") .process(emaiDBProcessor); } private String configureSqlTimer() { log.debug("configureSqlTimer() "); String pollingTime = emailProperties.getProperty("POLLING_TIME"); // 简化常量 String sqlTimer = "timer://pollFireFrgtTable?period=" + pollingTime + "s"; return sqlTimer; } }

在迁移到Camel 3.x时,开发者可能会发现原有的org.apache.camel.spring.Main类似乎不再可用,或者在新的org.apache.camel.main.Main类中找不到setApplicationContextUri这样的方法,这导致了Spring XML配置无法加载,且应用程序无法保持持续运行。

2. Camel 3.x Main 类的区分

Camel 3.x引入了模块化和更清晰的职责划分,导致存在两个主要的Main类,它们服务于不同的场景:

3. 解决方案:利用 camel-spring-main 构件

对于需要加载Spring XML上下文并保持Camel应用程序持续运行的Camel 3.x项目,正确的做法是使用org.apache.camel.spring.Main类。这个类提供了与Camel 2.x相似的API,使得迁移过程更为顺畅。

3.1. 更新后的代码示例

以下是Camel 3.x中如何使用org.apache.camel.spring.Main来启动应用程序的示例:

package com.foo.email.ffdb.listener;

import java.util.Properties;
import javax.annotation.Resource;
import org.apache.camel.builder.RouteBuilder;
// 关键:确保导入的是 org.apache.camel.spring.Main
import org.apache.camel.spring.Main;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;

// ... 其他导入

public class EmailDBListener extends RouteBuilder {
    private static final Logger log = LogManager.getLogger(EmailDBListener.class.getName());
    private static final String routeId = "EMAIL_ROUTE_ID"; // 简化常量

    @Autowired
    private EmailDBProcessor emaiDBProcessor; // 假设这是一个Spring Bean

    @Resource
    private Properties emailProperties; // 假设这是一个Spring Bean

    public static void main(String[] args) throws Exception {
        System.out.println("STARTING EMAILDBLISTENER");
        log.debug("Starting Email Batch ");

        // 在Camel 3.x中,用于Spring XML集成的正确Main类
        Main main = new Main();
        main.setApplicationContextUri("app-context.xml"); // 加载Spring XML上下文
        main.run(); // 启动并保持应用程序运行,直到接收到停止信号

        log.info("Email Batch Started:"); // 这行代码在应用程序运行期间不会被执行
    }

    @Override
    public void configure() throws Exception {
        log.debug("configure() ");
        from(configureSqlTimer())
            .routeId(routeId)
            .to("sqlComponent:{{SQL.READ_EMAIL_REQUESTS}}")
            .bean("fireForgetServiceMapper", "readEmailRequests") // fireForgetServiceMapper 假设是Spring Bean
            .process(emaiDBProcessor); // emaiDBProcessor 假设是Spring Bean
    }

    private String configureSqlTimer() {
        log.debug("configureSqlTimer() ");
        String pollingTime = emailProperties.getProperty("POLLING_TIME"); // 简化常量
        String sqlTimer = "timer://pollFireFrgtTable?period=" + pollingTime + "s";
        return sqlTimer;
    }
}

3.2. Maven 依赖配置

为了使用org.apache.camel.spring.Main,你需要在项目的pom.xml中添加camel-spring-main依赖。同时,确保你的Camel版本与Spring版本兼容。


    
    
        org.apache.camel
        camel-spring-main
        3.14.0 
    

    
    
        org.apache.camel
        camel-sql
        3.14.0
    
    
        org.apache.camel
        camel-timer
        3.14.0
    

    
    
        org.springframework
        spring-context
        5.3.14 
    

    
    
        org.apache.logging.log4j
        log4j-api
        2.17.1
    
    
        org.apache.logging.log4j
        log4j-core
        2.17.1
    

4. 关键注意事项和最佳实践

总结

在将Apache Camel应用程序从2.x迁移到3.x,并需要利用Spring XML上下文进行配置和实现长时运行的场景中,选择正确的Main类至关重要。通过使用camel-spring-main构件中的org.apache.camel.spring.Main类,开发者可以轻松地加载Spring XML配置,并确保Camel应用程序能够持续、稳定地运行,从而平滑地完成升级过程。