溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Java開發(fā)者如何入門Apache Camel

發(fā)布時(shí)間:2021-10-29 17:33:58 來(lái)源:億速云 閱讀:219 作者:柒染 欄目:編程語(yǔ)言

這篇文章給大家介紹Java開發(fā)者如何入門Apache Camel,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。

Apache Camel是一個(gè)非常實(shí)用的規(guī)則引擎庫(kù),能夠用來(lái)處理來(lái)自于不同源的事件和信息。你可以在使用不同的協(xié)議比如VM,HTTP,F(xiàn)TP,JMS甚至是文件系統(tǒng)中來(lái)傳遞消息,并且讓你的操作邏輯和傳遞邏輯保持分離,這能夠讓你更專注于消息的內(nèi)容。

在這篇文章中,我將提供一個(gè)Java語(yǔ)言(非Groovy)的Apache Camel入門演示。

首先創(chuàng)建一個(gè)Maven項(xiàng)目的pom.xml。

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="  http://maven.apache.org/POM/4.0.0  http://maven.apache.org/maven-v4_0_0.xsd">  <modelVersion>4.0.0</modelVersion> <groupId>camel-spring-demo</groupId> <artifactId>camel-spring-demo</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging>  <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <camel.version>2.11.1</camel.version> </properties>  <dependencies> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-core</artifactId> <version>${camel.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>1.7.5</version> </dependency> </dependencies>  </project>

在這里我們只用到了camel-core.jar包,實(shí)際上它提供了許多你可能用到的實(shí)用組件。出于日志記錄的目的,我使用了slf4j-simple來(lái)作為日志記錄的實(shí)現(xiàn),從而我們可以從控制臺(tái)上看到輸出。

接下來(lái)我們只需要構(gòu)造一個(gè)路由類。路由就好比是Camel中怎樣將消息從一端傳遞到另一端的一個(gè)指令定義。我們將會(huì)創(chuàng)建src/main/java /camelcoredemo/TimerRouteBuilder.java文件,每隔一秒向處理器發(fā)送一個(gè)消息,簡(jiǎn)單打印出來(lái)。

package camelcoredemo;   import org.slf4j.*;  import org.apache.camel.*;  import org.apache.camel.builder.*;   public class TimerRouteBuilder extends RouteBuilder {  static Logger LOG = LoggerFactory.getLogger(TimerRouteBuilder.class);  public void configure() {  from("timer://timer1?period=1000")  .process(new Processor() {  public void process(Exchange msg) {  LOG.info("Processing {}", msg);  }  });  }  }

以上就是這個(gè)示例的全部所需,現(xiàn)在編譯運(yùn)行。

bash> mvn compile  bash> mvn exec:java -Dexec.mainClass=org.apache.camel.main.Main -Dexec.args='-r camelcoredemo.TimerRouteBuilder'

注意,這里我們并沒(méi)有編寫Java類的main入口,我們只是將RouteBuilder的類名當(dāng)作參數(shù)簡(jiǎn)單傳遞給 org.apache.camel.main.Main,然后它將自動(dòng)加載路由。

控制CamelContext

當(dāng)啟動(dòng)Camel后,它會(huì)創(chuàng)建一個(gè)CamelContext對(duì)象,該對(duì)象擁有了很多關(guān)于如何運(yùn)行Camel的信息,還包含我們所創(chuàng)建的Route的定義?,F(xiàn)在如果你想通過(guò)CamelContext獲得更多的控制,那么你需要編寫自己的主類代碼。我在這舉個(gè)簡(jiǎn)單的例子。

package camelcoredemo;      import org.slf4j.*;  import org.apache.camel.*;  import org.apache.camel.impl.*;  import org.apache.camel.builder.*;      public class TimerMain {  static Logger LOG = LoggerFactory.getLogger(TimerMain.class);  public static void main(String[] args) throws Exception {  new TimerMain().run();  }  void run() throws Exception {  final CamelContext camelContext = new DefaultCamelContext();  camelContext.addRoutes(createRouteBuilder());  camelContext.setTracing(true);  camelContext.start();      Runtime.getRuntime().addShutdownHook(new Thread() {  public void run() {  try {  camelContext.stop();  } catch (Exception e) {  throw new RuntimeException(e);  }  }  });      waitForStop();  }  RouteBuilder createRouteBuilder() {  return new TimerRouteBuilder();  }  void waitForStop() {  while (true) {  try {  Thread.sleep(Long.MAX_VALUE);  } catch (InterruptedException e) {  break;  }  }  }  }

可以看到,我們?cè)赾reateRouteBuilder()方法中重用了已有的TimerRouteBuilder類。現(xiàn)在我們的主類對(duì)在什么時(shí)候創(chuàng)建、啟動(dòng)、停止CamelContext有了完全的控制。context(camelContext)對(duì)象允許你全局性地控制如何配置Camel,而不是在 Route級(jí)。它的JavaDoc鏈接給出了所有setter方法,你可以研究下它都可以做些什么。

注意到一點(diǎn),我們也需要在我們的主類中提供少量設(shè)置代碼。首先我們需要處理優(yōu)雅關(guān)閉的問(wèn)題,所以我們?cè)黾恿艘粋€(gè)Java關(guān)閉回調(diào)函數(shù)去調(diào)用context 的stop()方法。其次在context已經(jīng)啟動(dòng)后,我們需要增加一個(gè)線程阻塞。如果在啟動(dòng)后你不阻塞你的主線程,那么它會(huì)在啟動(dòng)后就簡(jiǎn)單的退出了,那就沒(méi)啥用了。你會(huì)把Camel一直作為一個(gè)服務(wù)(就像一個(gè)服務(wù)器)運(yùn)行,直至你按下CTRL+C鍵去終止該進(jìn)程。

改善啟動(dòng)CamelContext的主類

如果你不想像上面例子一樣過(guò)多的處理主類設(shè)置代碼,那么你可以簡(jiǎn)單地繼承由camel-core提供的 org.apache.camel.main.Main類作為代替。通過(guò)利用這個(gè)類,你不僅可以讓你的context自動(dòng)設(shè)置,還可以獲得所有附加的命令行特性,比如控制進(jìn)程運(yùn)行多久,啟用追蹤,加載自定義route類等等。

重構(gòu)了下上一個(gè)例子,代碼如下:

package camelcoredemo;   import org.slf4j.*;  import org.apache.camel.builder.*;  import org.apache.camel.main.Main;   public class TimerMain2 extends Main {  static Logger LOG = LoggerFactory.getLogger(TimerMain2.class);  public static void main(String[] args) throws Exception {  TimerMain2 main = new TimerMain2();  main.enableHangupSupport();  main.addRouteBuilder(createRouteBuilder());  main.run(args);  }  static RouteBuilder createRouteBuilder() {  return new TimerRouteBuilder();  }  }

現(xiàn)在TimerMain2類的代碼比之前的更少了,你可以試試看,它應(yīng)該和之前的功能一樣。

bash> mvn compile  bash> mvn exec:java -Dexec.mainClass=camelcoredemo.TimerMain2 -Dexec.args='-t'

注意到我們給出-t選項(xiàng)后,會(huì)轉(zhuǎn)儲(chǔ)Route追蹤。使用-h會(huì)看到所有可用的選項(xiàng)。

用Camel的注冊(cè)機(jī)制添加bean

在之前的TimerRouteBuilder例子中,我們已經(jīng)在代碼中創(chuàng)建了一個(gè)匿名Processor?,F(xiàn)在如果你想將幾個(gè)不同的Processor放在一起,那么使用Camel的注冊(cè)機(jī)制添加bean的方式將能更好的減少代碼混亂。Camel允許你通過(guò)將processing當(dāng)作bean注入到它的 registry space,然后你只要把它們當(dāng)作bean組件來(lái)進(jìn)行調(diào)用。如下是我的重構(gòu)代碼:

package camelcoredemo;   import org.slf4j.*;  import org.apache.camel.*;  import org.apache.camel.builder.*;  import org.apache.camel.main.Main;   public class TimerBeansMain extends Main {  static Logger LOG = LoggerFactory.getLogger(TimerBeansMain.class);  public static void main(String[] args) throws Exception {  TimerBeansMain main = new TimerBeansMain();  main.enableHangupSupport();  main.bind("processByBean1", new Bean1());  main.bind("processAgainByBean2", new Bean2());  main.addRouteBuilder(createRouteBuilder());  main.run(args);  }  static RouteBuilder createRouteBuilder() {  return new RouteBuilder() {  public void configure() {  from("timer://timer1?period=1000")  .to("bean:processByBean1")  .to("bean:processAgainByBean2");  }  };  }   // Processor beans  static class Bean1 implements Processor {  public void process(Exchange msg) {  LOG.info("First process {}", msg);  }  }  static class Bean2 implements Processor {  public void process(Exchange msg) {  LOG.info("Second process {}", msg);  }  }  }

現(xiàn)在Route類更簡(jiǎn)潔明了,同時(shí)處理代碼也被重構(gòu)到了獨(dú)立的類中。當(dāng)你需要編寫很復(fù)雜的Route來(lái)實(shí)現(xiàn)業(yè)務(wù)邏輯時(shí),這種方式能夠幫助你更好的組織和測(cè)試你的代碼。它能夠讓你構(gòu)建像”樂(lè)高“積木那樣可復(fù)用的POJO bean。Camel的registry space同樣可用于其他很多用途,比如你可以自定義許多具有附加功能的endpoint組件或者注冊(cè)一些信息,更或者替換線程池實(shí)現(xiàn)策略之內(nèi)的事情。

上述Route示例是用所謂的Java DSL來(lái)構(gòu)成的,它的可讀性較高,你可以用IDE提供的支持查看所有可用于Route的方法。

我希望這篇文章能夠幫助你跳過(guò)Camel的摸索階段。除了已經(jīng)提到的事件組件之外,camel還提供了如下組件:

  • bean component

  • browse component

  • dataset component

  • direct component

  • file component

  • log component

  • mock component

  • properties component

  • seda component

  • test component

  • timer component

  • stub component

  • validator component

  • vm component

  • xslt component

Have fun!

關(guān)于Java開發(fā)者如何入門Apache Camel就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI