Apache Camel x Spring Boot の ProcessorとBean を呼び出す

![IMG_0741.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4063686/024f7af0-bc08-4719-b12d-026e446709cb.jpeg)

## はじめに

Apache Camel x Spring Boot（Camel 4, XML DSL）でルート定義を XML DSL で記述する場合、Spring Boot 側で DI した Bean をそのまま `camel-context.xml` から呼び出すことができます。

この記事では、以下のような疑問を解消しつつ、**Processor と Bean の使い分け**について整理します：

- `@Component` で定義した Bean をどうやって XML から使うのか？
- Bean 名はどう決まるのか？先頭は小文字にするのか？
- `<process>` と `<bean>` の違いは？
- `<bean>` のメソッドに `Exchange` やヘッダーを引数として渡せるのか？

---

## Spring Bean の呼び出し方

### 1. 自動登録される Bean 名のルール

```java
@Component
public class MyProcessor implements Processor {
    ...
}
```

このように `@Component` を付けたクラスは、**クラス名の先頭を小文字にした Bean 名（ここでは `myProcessor`）** として自動登録されます。

#### 明示的に名前を指定したい場合

```java
@Component("customProcessor")
public class MyProcessor implements Processor {
    ...
}
```

この場合、Bean 名は `customProcessor` になります。

---

### 2. `<process>` と `<bean>` の違い

| 項目 | `<process>` | `<bean>` |
|------|-------------|----------|
| 対象クラス | `Processor` を実装 | 任意のクラス |
| 呼び出し形式 | `process(Exchange)` メソッド固定 | 任意のメソッド（引数も柔軟） |
| 使いどころ | Camel のルーティング処理に組み込む場合 | データ加工や変換処理など柔軟な処理 |

---

#### `<process>` の例

```java
@Component("myProcessor")
public class MyProcessor implements Processor {
    public void process(Exchange exchange) {
        ...
    }
}
```

```xml
<route>
    <from uri="timer:foo?period=1000"/>
    <process ref="myProcessor"/>
</route>
```

---

#### `<bean>` の例（メソッド引数に Exchange を使う）

```java
@Component("myBean")
public class MyBean {
    public void handle(Exchange exchange) {
        ...
    }
}
```

```xml
<route>
    <from uri="timer:bar?period=1000"/>
    <bean ref="myBean" method="handle"/>
</route>
```

---

### 3. `<bean>` では Exchange やヘッダーも引数にできる

```java
@Component("myBean")
public class MyBean {
    public String transform(@Body String body, @Header("userId") String userId) {
        return "[" + userId + "] " + body;
    }
}
```

```xml
<route>
    <from uri="direct:start"/>
    <setHeader headerName="userId">
        <constant>u-001</constant>
    </setHeader>
    <setBody>
        <constant>Hello</constant>
    </setBody>
    <bean ref="myBean" method="transform"/>
</route>
```

Camel はメソッド引数の型やアノテーションに応じて、以下のように自動で値を渡してくれます：

| 型・アノテーション | 渡される内容 |
|--------------------|--------------|
| `Exchange`         | Exchange 全体 |
| `Message`          | Exchange の message 部分 |
| `@Body`            | メッセージの body |
| `@Header("xxx")`   | 指定されたヘッダー |
| `@Headers`         | 全ヘッダーの Map |

---

## おまけ：DI された Bean を一覧表示したいとき

Camel に限らず、Spring Boot アプリでどんな Bean が登録されているかを確認したい場合は、以下のようなコードで一覧出力できます：

```java
@Component
public class BeanLister implements CommandLineRunner {
    @Autowired
    private ApplicationContext applicationContext;

    @Override
    public void run(String... args) {
        Arrays.stream(applicationContext.getBeanDefinitionNames())
            .sorted()
            .forEach(name -> {
                Object bean = applicationContext.getBean(name);
                System.out.printf("Bean name: %-40s | Type: %s%n", name, bean.getClass().getName());
            });
    }
}
```

このコードを使うと、アプリ起動時にすべての DI 済み Bean をコンソールに出力できます。  
**`Processor` や `@Component("xxx")` で登録したクラスの名前と型も一覧に含まれます。**

---

## おわりに

Camel 4 + Spring Boot 環境では、Spring Bean を XML DSL から自然に呼び出せるため、**ルート定義とビジネスロジックを柔軟に分離**できます。

特に `<bean>` を使えば、簡単な変換処理やユーティリティクラスの呼び出しなども非常にスマートに実装できます。  
一方で、ルーティング制御や例外処理などは `Processor` として定義した方が適しています。

用途に応じて `<process>` と `<bean>` をうまく使い分けることで、Camel の設計をよりシンプルかつ保守しやすくできます。