Apache Camel × Spring Boot で application.properties と環境変数を使いこなす

![11934FBB-7B7F-42E8-BFBC-3ACC5A92885C.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4063686/a015aae6-7d25-45ce-805a-9c1cfbd9ba2b.png)

## はじめに

Apache Camel と Spring Boot を組み合わせた XML DSL プロジェクトでは、設定値（Kafkaトピック名、リトライ回数など）を柔軟かつ安全に管理する必要があります。

この記事では、以下を満たす構成方法を実例付きで解説します：

- `application.properties` でデフォルト値を定義  
- 環境変数で上書きできるようにする  
- Camel の XML DSL からプロパティを参照する  
- Java の Processor / Bean でもプロパティを使う

---

## 1. プロパティの基本構成

| 設定元 | 用途 | 特徴 |
|--------|------|------|
| `application.properties` | デフォルト値の定義 | Git で管理しやすい |
| 環境変数 | 環境ごとの切り替え | Spring Boot が自動で解決 |
| Camel XML DSL | プロパティの使用 | `{{...}}` で参照 |
| Java Bean / Processor | 値の取得 | `@Value` または `Environment` |

---

## 2. application.properties で環境変数を参照する

```properties
# application.properties
myapp.kafka.topic=${MYAPP_KAFKA_TOPIC:default-topic}
myapp.retry.count=${MYAPP_RETRY_COUNT:3}
```

---

## 3. Camel XML DSL でプロパティを使う

```xml
<routes xmlns="http://camel.apache.org/schema/spring">
  <route id="kafka-receive">
    <from uri="kafka:{{myapp.kafka.topic}}"/>
    <log message="Processing from topic: {{myapp.kafka.topic}}"/>
  </route>
</routes>
```

---

## 4. Java Bean / Processor でのプロパティ使用

### 方法①: `@Value` を使う

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

  @Value("${myapp.retry.count}")
  private int retryCount;

  @Override
  public void process(Exchange exchange) {
    System.out.println("Retry Count = " + retryCount);
  }
}
```

### 方法②: `Environment` を使って取得

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

  @Autowired
  private Environment env;

  @Override
  public void process(Exchange exchange) {
    String topic = env.getProperty("myapp.kafka.topic");
    System.out.println("Kafka Topic = " + topic);
  }
}
```

---

## 5. 環境ごとの設定切り替え

```bash
export MYAPP_KAFKA_TOPIC=production-topic
export MYAPP_RETRY_COUNT=5
```

---

## 6. プロパティ命名規則と変換ルール

| application.properties | 環境変数 | 補足 |
|------------------------|----------|------|
| `myapp.kafka.topic`    | `MYAPP_KAFKA_TOPIC` | ドットがアンダースコアに変換される |
| `aws.kinesis.stream.name` | `AWS_KINESIS_STREAM_NAME` | サブキーも対応可能 |

---

## 7. プロパティの優先順位

1. コマンドライン引数（--key=value）  
2. OSの環境変数  
3. `application-{profile}.properties`  
4. `application.properties`  
5. Javaコード内のデフォルト値

---

## 8. よくあるハマりポイント

| 現象 | 原因・対策 |
|------|------------|
| 環境変数を設定したのに反映されない | 命名ルールに注意（アンダースコア＋大文字） |
| XML DSL の `{{key}}` が解決されない | プロパティ解決対象に含まれていない |
| Java の `@Value` と XML DSL の構文の違い | `@Value` は `${}`、XML は `{{}}` |

---

## 8.5 プロパティ値のバリデーション（＠ConfigurationProperties + ＠Validated）

環境変数や `application.properties` の値をそのまま使うと、不正な値が設定されても気づかないリスクがあります。  
Spring Boot では `@ConfigurationProperties` と `@Validated` を組み合わせることで、起動時に設定値のバリデーションを行うことができます。

### Step 1: application.properties にデフォルト値を定義

```properties
myapp.retry.count=${MYAPP_RETRY_COUNT:3}
```

### Step 2: プロパティクラスを作成してバリデーションを追加

```java
@Validated
@ConfigurationProperties(prefix = "myapp")
public class MyAppProperties {

    @Min(1)
    @Max(10)
    private int retryCount;

    public int getRetryCount() {
        return retryCount;
    }

    public void setRetryCount(int retryCount) {
        this.retryCount = retryCount;
    }
}
```

### Step 3: アプリに登録

```java
@SpringBootApplication
@EnableConfigurationProperties(MyAppProperties.class)
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
```

### Step 4: Camel Processor などで安全に参照

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

    private final MyAppProperties props;

    public MyProcessor(MyAppProperties props) {
        this.props = props;
    }

    @Override
    public void process(Exchange exchange) {
        System.out.println("Retry count = " + props.getRetryCount());
    }
}
```

### バリデーションエラー時の例（起動失敗）

```
Binding to target com.example.config.MyAppProperties failed:
Property: myapp.retryCount
Value: -1
Reason: must be greater than or equal to 1
```

---

## 9. まとめ

- application.properties はデフォルト値、環境変数は本番環境向け切り替えに便利  
- Camel XML DSL や Java Bean から同じプロパティを扱える構成がベスト  
- 命名と優先順位を意識すれば柔軟かつ安全な設定が可能  

---