3.2. Spring Boot
Spring Boot は Camel を自動的に設定します。Camel コンテキストの独自の autoconfiguration は、Spring コンテキストで使用可能な Camel ルートを自動検出し、主要な Camel ユーティリティー (producer サーテンプレート、コンシューマーテンプレート、型コンバーターなど) を Bean として登録します。
Maven ユーザーは、このコンポーネントを使用するために pom.xml に次の依存関係を追加する必要があります。
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-spring-boot</artifactId>
</dependency>
camel-spring-boot jar には spring.factories ファイルが付属しているため、その依存関係をクラスパスに追加するとすぐに、Spring Boot によって Camel が自動的に設定されます。
3.2.1. Camel Spring Boot スターター リンクのコピーリンクがクリップボードにコピーされました!
Apache Camel には、Spring Boot Starter モジュールが同梱されています。このモジュールを使用すると、スターターを使用して Spring Boot アプリケーションを開発できます。
サンプルリポジトリーには サンプルアプリケーション も用意されています。
スターターを使用するには、Spring Boot pom.xml ファイルに以下を追加します。
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
</dependency>
さらに、次のような Camel ルートでクラスを追加します。
package com.example;
import org.apache.camel.builder.RouteBuilder;
import org.springframework.stereotype.Component;
@Component
public class MyRoute extends RouteBuilder {
@Override
public void configure() throws Exception {
from("timer:foo").to("log:bar");
}
}
その後、これらのルートは自動的に開始されます。
application.properties または application.yml ファイルで Camel アプリケーションをカスタマイズできます。
3.2.2. Spring Boot 自動設定 リンクのコピーリンクがクリップボードにコピーされました!
Spring Boot で spring-boot を使用する場合は、自動設定をサポートするために必ず次の Maven 依存関係を使用してください。
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-spring-boot-starter</artifactId>
</dependency>
3.2.3. 自動設定された Camel コンテキスト リンクのコピーリンクがクリップボードにコピーされました!
Camel 自動設定によって提供される最も重要な機能は、CamelContext インスタンスです。Camel 自動設定は、SpringCamelContext を作成し、そのコンテキストの適切な初期化とシャットダウンを処理します。作成された Camel コンテキストは、Spring アプリケーションコンテキストにも (camelContext Bean 名で) 登録されるため、他の Spring Bean と同じようにアクセスできます。
@Configuration
public class MyAppConfig {
@Autowired
CamelContext camelContext;
@Bean
MyService myService() {
return new DefaultMyService(camelContext);
}
}
3.2.4. Camel ルートの自動検出 リンクのコピーリンクがクリップボードにコピーされました!
Camel 自動設定は、Spring コンテキストからすべての RouteBuilder インスタンスを収集し、提供された CamelContext にこれらのインスタンスを自動的に注入します。そのため、Spring Boot スターターを使用して新しい Camel ルートを作成するのは、@Component アノテーション付きクラスをクラスパスに追加するのと同じくらい簡単です。
@Component
public class MyRouter extends RouteBuilder {
@Override
public void configure() throws Exception {
from("jms:invoices").to("file:/invoices");
}
}
または、新しいルートの RouteBuilder Bean を @Configuration クラスで作成します。
@Configuration
public class MyRouterConfiguration {
@Bean
RoutesBuilder myRouter() {
return new RouteBuilder() {
@Override
public void configure() throws Exception {
from("jms:invoices").to("file:/invoices");
}
};
}
}
3.2.5. Camel プロパティー リンクのコピーリンクがクリップボードにコピーされました!
Spring Boot の自動設定は、Camel プロパティーのサポートを使用して Spring Boot 外部設定 (プロパティーのプレースホルダー、OS 環境変数、またはシステムプロパティーを含む) に自動的に接続します。そのため、基本的に、次のように application.properties ファイルで定義されているプロパティーや、
route.from = jms:invoices
次のようにシステムプロパティーを介して設定されているプロパティーを、
java -Droute.to=jms:processed.invoices -jar mySpringApp.jar
次のように Camel ルートのプレースホルダーとして使用できます。
@Component
public class MyRouter extends RouteBuilder {
@Override
public void configure() throws Exception {
from("{{route.from}}").to("{{route.to}}");
}
}
3.2.6. カスタムの Camel コンテキスト設定 リンクのコピーリンクがクリップボードにコピーされました!
Camel 自動設定によって作成された CamelContext Bean でいくつかの操作を実行する場合は、Spring コンテキストに CamelContextConfiguration インスタンスを登録します。
@Configuration
public class MyAppConfig {
@Bean
CamelContextConfiguration contextConfiguration() {
return new CamelContextConfiguration() {
@Override
void beforeApplicationStart(CamelContext context) {
// your custom configuration goes here
}
};
}
}
beforeApplicationStart メソッドは Spring コンテキストが開始される直前に呼び出されるため、このコールバックに渡される CamelContext インスタンスは完全に自動設定されます。CamelContextConfiguration の複数のインスタンスを Spring コンテキストに追加すると、各インスタンスが実行されます。
サンプルアプリケーションは、camel-spring-boot-examples リポジトリーの Metrics の例を参照してください。
3.2.7. 自動設定されたコンシューマーおよびプロデューサーのテンプレート リンクのコピーリンクがクリップボードにコピーされました!
Camel 自動設定によって、事前設定された ConsumerTemplate および ProducerTemplate インスタンスが提供されます。それらを Spring 管理の Bean に簡単に注入できます。
@Component
public class InvoiceProcessor {
@Autowired
private ProducerTemplate producerTemplate;
@Autowired
private ConsumerTemplate consumerTemplate;
public void processNextInvoice() {
Invoice invoice = consumerTemplate.receiveBody("jms:invoices", Invoice.class);
...
producerTemplate.sendBody("netty-http:http://invoicing.com/received/" + invoice.id());
}
}
デフォルトでは、コンシューマーテンプレートとプロデューサーテンプレートのエンドポイントキャッシュサイズは 1000 に設定されています。これらの値は、次の Spring プロパティーを変更することで変更できます。
camel.springboot.consumer-template-cache-size = 100
camel.springboot.producer-template-cache-size = 200
3.2.8. 自動設定された TypeConverter リンクのコピーリンクがクリップボードにコピーされました!
Camel 自動設定では、Spring コンテキストの typeConverter という名前の TypeConverter インスタンスを登録します。
@Component
public class InvoiceProcessor {
@Autowired
private TypeConverter typeConverter;
public long parseInvoiceValue(Invoice invoice) {
String invoiceValue = invoice.grossValue();
return typeConverter.convertTo(Long.class, invoiceValue);
}
}
3.2.8.1. Spring タイプコンバージョン API ブリッジ リンクのコピーリンクがクリップボードにコピーされました!
Spring には、強力な タイプコンバージョン API が付属しています。Spring API は Camel の型コンバーター API と似ています。両方の API は非常に似ているため、Camel Spring Boot は、Spring コンバージョン API に委譲するブリッジコンバーター (SpringTypeConverter) を自動的に登録します。そのため、初期状態の Camel は Spring コンバーターを Camel コンバーターと同様に扱います。このアプローチでは、Camel TypeConverter API 経由でアクセスする Camel コンバーターと Spring コンバーターの両方を使用できます。
@Component
public class InvoiceProcessor {
@Autowired
private TypeConverter typeConverter;
public UUID parseInvoiceId(Invoice invoice) {
// Using Spring's StringToUUIDConverter
UUID id = invoice.typeConverter.convertTo(UUID.class, invoice.getId());
}
}
Camel Spring Boot は内部で、アプリケーションコンテキストで利用可能な Spring の ConversionService インスタンスに変換を委譲します。ConversionService インスタンスが利用できない場合は、Camel Spring Boot 自動設定によってインスタンスが作成されます。
サンプルアプリケーションは、camel-spring-boot-examples リポジトリーの Type converter の例を参照してください。
3.2.9. アプリケーションの存続 リンクのコピーリンクがクリップボードにコピーされました!
この機能が有効になっている Camel アプリケーションは、JVM の終了を防止してアプリケーションを存続させることのみを目的として、起動時に新しいスレッドを起動します。つまり、Spring Boot で Camel アプリケーションを開始した後、アプリケーションは Ctrl+C シグナルを待機し、すぐには終了しません。
コントローラースレッドは、camel.springboot.main-run-controller を true に設定することでアクティブ化できます。
camel.springboot.main-run-controller = true
Web モジュールを使用するアプリケーション (たとえば org.springframework.boot:spring-boot-web-starter モジュールをインポートするアプリケーション) は、他の非デーモンスレッドの存在によってアプリケーションが維持されるため、通常この機能を使用する必要はありません。
サンプルアプリケーションは、camel-spring-boot-examples リポジトリーの POJO の例を参照してください。
3.2.10. XML ルートの追加 リンクのコピーリンクがクリップボードにコピーされました!
デフォルトでは、Camel XML ルートをディレクトリー camel の下のクラスパスに配置できます。このルートは、camel-spring-boot によって自動検出されて組み込まれます。設定オプションを使用すると、ディレクトリー名を設定したり、この機能を無効化できます。
# turn off
camel.springboot.routes-include-pattern = false
# scan only in the com/foo/routes classpath
camel.springboot.routes-include-pattern = classpath:com/foo/routes/*.xml
XML ファイルは、(<CamelContext> ではなく) 次のような Camel XML ルートである必要があります。
<routes xmlns="http://camel.apache.org/schema/spring">
<route id="test">
<from uri="timer://trigger"/>
<transform>
<simple>ref:myBean</simple>
</transform>
<to uri="log:out"/>
</route>
</routes>
サンプルアプリケーションは、camel-spring-boot-examples リポジトリーの XML の例を参照してください。
3.2.11. JUnit 5 方式のテスト リンクのコピーリンクがクリップボードにコピーされました!
テストのために、Maven ユーザーは次の依存関係を pom.xml に追加する必要があります。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>3.4.9</version> <!-- Use the same version as your Spring Boot version -->
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-test-spring-junit5</artifactId>
<version>4.10.6.redhat-00008</version> <!-- use the same version as your Camel core version -->
<scope>test</scope>
</dependency>
Camel Spring Boot アプリケーションをテストするには、テストクラスに @CamelSpringBootTest のアノテーションを付けます。これにより、Camel の Spring Test サポートがアプリケーションに提供されるため、Spring Boot テスト規則 を使用してテストを作成できるようになります。
CamelContext または ProducerTemplate を取得するには、@Autowired を使用して、Spring の通常の方法でクラスに注入できます。
camel-test-spring-junit5 を使用して、テストを宣言的に設定することもできます。この例では、@MockEndpoints アノテーションを使用して、エンドポイントを自動モックします。
@CamelSpringBootTest
@SpringBootApplication
@MockEndpoints("direct:end")
public class MyApplicationTest {
@Autowired
private ProducerTemplate template;
@EndpointInject("mock:direct:end")
private MockEndpoint mock;
@Test
public void testReceive() throws Exception {
mock.expectedBodiesReceived("Hello");
template.sendBody("direct:start", "Hello");
mock.assertIsSatisfied();
}
}
サンプルアプリケーションは、camel-spring-boot-examples リポジトリーの Infinispan の例を参照してください。
@CamelSpringBootTest は @SpringBootTest の機能を継承します。これには、ルートテストユーティリティーの提供、CamelContext、ルートアドバイザー、およびモックエンドポイントの追加、Camel テストアノテーションの有効化、@MockEndpoints、@UseAdviceWith との連携といった機能が含まれます。
@UseAdviceWith の例としては、実行時にルートの変更が適用された場合が挙げられます。
@CamelSpringBootTest
@SpringBootApplication
public class MySpringBootApplicationTest {
@Autowired
private CamelContext camelContext;
@Autowired
private ProducerTemplate producerTemplate;
public static void main(String[] args) {
SpringApplication.run(MySpringBootApplicationTest.class, args);
}
// Spring context fixtures
@Configuration
static class TestConfig {
@Bean
RoutesBuilder route() {
return new RouteBuilder() {
@Override
public void configure() throws Exception {
from("timer:hello1?period={{timer.period}}").routeId("hello1")
.transform().method("myBean", "saySomething")
.filter(simple("${body} contains 'foo'"))
.to("log:foo")
.end()
.to("stream:out");
}
};
}
}
@Test
public void test() throws Exception {
// Apply advice before getting the mock endpoint
AdviceWith.adviceWith(camelContext, "hello1",
// intercepting an exchange on route
r -> {
// replacing consumer with direct component
r.replaceFromWith("direct:start");
// mocking producer
r.mockEndpoints("stream*");
}
);
// Start the context after applying advice
camelContext.start();
// Get mock endpoint after advice is applied
MockEndpoint mock = camelContext.getEndpoint("mock:stream:out", MockEndpoint.class);
// setting expectations
mock.expectedMessageCount(1);
mock.expectedBodiesReceived("Hello World");
// invoking consumer
producerTemplate.sendBody("direct:start", null);
// asserting mock is satisfied
mock.assertIsSatisfied();
}
}
場合によっては、applicationContext が厳密に必要な場合は、@CamelSpringBootTest と @SpringBootTest の両方の組み合わせを宣言する必要があります。その場合は、使用する設定クラスを指定する @SpringBootTest(classes = DocTest.TestApplication.class) を追加するだけです。
@CamelSpringBootTest
@SpringBootTest(classes = MySpringBootApplicationTest.TestConfig.class)
@SpringBootApplication
@MockEndpoints("direct:end")
public class MySpringBootApplicationTest {
@Autowired
private ProducerTemplate template;
@EndpointInject("mock:direct:end")
private MockEndpoint mock;
@Configuration
static class TestConfig {
@Bean
RoutesBuilder route() {
return new RouteBuilder() {
@Override
public void configure() throws Exception {
from("direct:start").routeId("hello2")
.setBody(simple("Hello World"))
.log("Received: ${body}")
.to("direct:end");
from("direct:end")
.log("${body}");
}
};
}
}
@Test
public void testReceive() throws Exception {
mock.expectedMessageCount(1);
mock.expectedBodiesReceived("Hello World");
template.sendBody("direct:start", null);
mock.assertIsSatisfied();
}
}
もう 1 つのアプローチは、従来の Spring XML コンテキスト設定をテストすることです。この場合、@ContextConfiguration を使用して XML ファイルを指定し、依存性注入を使用してメイン Camel ランタイムコンテキストを取得する必要があります。
@Autowired
protected CamelContext camelContext;
次に、各テストメソッドの後に Spring ApplicationContext をリロードするには、次を使用します。
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
代替モード: BEFORE_CLASS、AFTER_CLASS、BEFORE_EACH_TEST_METHOD
完全な例を次に示します。
package com.redhat.plain;
.....
@CamelSpringBootTest
@ContextConfiguration
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
public class MySpringBootApplicationPlainTest {
@Autowired
protected CamelContext camelContext;
@EndpointInject("mock:a")
protected MockEndpoint mockA;
@Produce("direct:start")
protected ProducerTemplate start;
@Test
public void testPositive() throws Exception {
assertEquals(ServiceStatus.Started, camelContext.getStatus());
start.sendBody("Hello");
MockEndpoint.assertIsSatisfied(camelContext);
mockA.expectedBodiesReceived("Hello");
}
}
Spring XML コンテキストは、命名パターン className-context.xml を使用して、宣言されたクラスパッケージ com.redhat.plain のリソースに配置する必要があります。
プロジェクト構造
src/
├── main/
│ ├── java/
│ │ └── com/redhat/
│ │ ├── Application.java
│ │ └── route/
│ │ └── MyRoute.java
│ └── resources/
│ └── application.yml
└── test/
├── java/
│ └── com/redhat/
└── resources/
└── MySpringBootApplicationPlainTest-context.yml
上記の例の 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
">
<!-- Camel Context configuration -->
<camelContext id="camelContext" xmlns="http://camel.apache.org/schema/spring">
<route xmlns="http://camel.apache.org/schema/spring" id="helloX">
<from id="from1" uri="direct:start"/>
<filter id="filter1">
<simple>${body} contains 'foo'</simple>
<to id="to1" uri="log:foo"/>
</filter>
<to id="to2" uri="stream:out"/>
</route>
</camelContext>
</beans>