Apache Camel — очень полезная библиотека, которая помогает вам обрабатывать события или сообщения из разных источников. Вы можете перемещать эти сообщения по многим различным протоколам, таким как между ВМ, HTTP, FTP, JMS или даже DIRECTORY / FILE, и при этом сохранять код обработки свободным от транспортной логики. Это позволяет вам сконцентрироваться на переваривании содержимого сообщений.
Здесь я приведу учебное пособие о том, как начать работу с Apache Camel, используя Java вместо Groovy .
Начнем с создания pom.xml
файла проекта Maven .
<?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
, который на самом деле содержит довольно мало полезных компонентов, которые вы можете использовать. Также для целей ведения журнала я добавил slf4j-simple
в качестве реализации средства ведения журнала, чтобы мы могли видеть вывод на консоли.
Далее вам просто нужен класс для создания Route
. A Route
подобен определению инструкции для Camel о том, как перемещать ваши сообщения из одной точки в другую. Мы собираемся создать src/main/java/camelcoredemo/TimerRouteBuilder.java
файл, который будет генерировать сообщение таймера каждую секунду, а затем передавать процессору, который просто регистрирует его.
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); } }); } }
Это все, что вам нужно для начала. Теперь вы можете создать и запустить эту простую демонстрацию.
bash> mvn compile bash> mvn exec:java -Dexec.mainClass=org.apache.camel.main.Main -Dexec.args='-r camelcoredemo.TimerRouteBuilder'
Обратите внимание, что мы даже не написали основной класс Java , а просто использовали org.apache.camel.main.Main
опцию, чтобы принять RouteBuilder
имя класса в качестве параметра. Затем он загрузит и создаст маршрут автоматически.
Контролировать CamelContext
Когда вы запускаете Camel, он создает CamelContext
объект, который содержит много информации о том, как его запустить, включая определение, которое Route
мы создали. Теперь, если вы хотите иметь больше контроля над этим CamelContext
, вам нужно написать свой собственный Main
класс. Я покажу вам простой здесь.
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; } } } }
Как видите, мы повторно использовали существующий TimerRouteBuilder
класс внутри createRouteBuilder()
метода. Наш Main
класс теперь имеет полный контроль над тем, когда создавать, запускать и останавливать CamelContext
. Этот контекст позволяет вам контролировать настройку Camel глобально, а не на Route
уровне. Ссылка javadoc предоставляет все методы установки, которые вы можете изучить, что он может делать.
Заметил, что нам также нужно предоставить несколько кодов настройки в нашем Main
классе. Сначала нам нужно обработать корректное завершение работы, поэтому мы добавили ловушку Java shutdown для вызова контекста stop()
. Во-вторых, нам нужно добавить блок потока после запуска контекста. Причина этого в том, что CamelContext#start()
метод неблокирующий! Если вы не заблокируете свой Main
поток после запуска, он просто выйдет сразу после него, что не будет иметь большого значения. Вы хотите запускать Camel как службу (например, сервер), пока не нажмете явно, CTRL+C
чтобы завершить процесс.
Улучшение Main
класса для начала CamelContext
Если вы не хотите иметь дело с большей частью Main
кода установки класса, такого как выше, то вы можете просто расширить org.apache.camel.main.Main
класс, предоставляемый camel-core
intead. Если вы вернетесь к этому классу, у вас не будет автоматической настройки контекста, но вы получите все дополнительные функции командной строки, такие как управление продолжительностью процесса, включение трассировки, загрузка пользовательского класса маршрута и т. Д.
Рефакторинг предыдущего примера, вот как это выглядит.
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(); } }
Теперь наша система TimerMain2
намного короче, и вы можете попробовать ее, и она должна функционировать так же, как и раньше.
bash> mvn compile bash> mvn exec:java -Dexec.mainClass=camelcoredemo.TimerMain2 -Dexec.args='-t'
Обратите внимание, что мы указали -t
опцию, и она сбросит Route
трассировку. Используйте, -h
и вы увидите все доступные варианты.
Добавление бобов к верблюду Registry
В TimerRouteBuilder
приведенном выше примере мы создали Processor
на лету. Теперь, если бы вы объединили несколько разных Processor
вместе, было бы лучше минимизировать шум. Camel позволяет вам делать это, регистрируя компоненты обработки в их пространстве реестра, а затем вы просто указываете их в своем маршруте как bean
компонент. Вот как я могу преобразовать приведенный выше пример в обработку bean-компонентов.
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); } } }
Теперь вы видите мой Route
очень тонкий и без шумового шума; и я реорганизовал мой код обработки в отдельные классы. Это способствует более эффективному управлению и тестированию кода, поскольку вы пишете более сложную Route
для решения бизнес-логики. Это позволило вам создать LEGO-подобный блок повторно используемых бобов POJO. Помимо обработки бобов, Camel использует это пространство реестра и для многих других сервисов. Например, вы можете настроить многие другие конечные точки компонентов с помощью дополнительных функций и / или конфигураций. Или такая вещь, как замена реализации стратегии пула потоков и т. Д.
Приведенный Route
выше пример построен с использованием так называемой Java DSL. Маршрут очень удобен для чтения, но вы получите полную поддержку IDE для просмотра всех методов, доступных для вашего маршрута.
Я надеюсь, что эта статья помогла вам начать езду на верблюде. Помимо timer
упомянутого компонента, в комплект поставки camel-core
входят следующие компоненты.
Повеселись!