120 lines
14 KiB
Markdown
120 lines
14 KiB
Markdown
---
|
|
title: Spring Boot Auto-configuration + custom starter 공식 문서
|
|
source_type: official-doc
|
|
url: https://docs.spring.io/spring-boot/reference/features/developing-auto-configuration.html
|
|
archive_url:
|
|
status: raw
|
|
confidence: high
|
|
related_branches: [feature-integration-adapter-templates, feature-architecture-enforcement-rules, feature-runtime-health-lifecycle-contract, feature-skeleton-package-blueprint-contract]
|
|
related_projects: [ca-tmpl]
|
|
tags: [ca-tmpl, adapter, spring-boot, auto-configuration, conditional-on-property, custom-starter]
|
|
created: 2026-05-22
|
|
last_reviewed: 2026-05-27
|
|
---
|
|
|
|
# Spring Boot Auto-configuration + Custom Starter
|
|
|
|
> Layer: `raw/official-docs/` — Spring Boot 3.5 reference "Developing Auto-configuration" + `@ConditionalOnProperty` / `@ConditionalOnBooleanProperty` Javadoc 발췌. ca-tmpl 그룹 G-I (`feature-integration-adapter-templates`) 의 **adapter on/off 채택안** 1차 근거.
|
|
|
|
## Parent / 활용 branch (필수)
|
|
|
|
| Branch | 이 자료가 정당화하는 결정 |
|
|
|---|---|
|
|
| [[raw/branch-notes/feature-integration-adapter-templates]] | optional adapter 의 `@ConditionalOnProperty(name="app.adapter.{adapterName}.enabled", havingValue="true")` 결정 — Layer 1 메커니즘의 정확한 공식 시맨틱 |
|
|
| [[raw/branch-notes/feature-architecture-enforcement-rules]] | ArchUnit Layer 2 검사가 Spring 공식 cover 밖이라는 분리 근거 (본 문서는 Layer 1 만 cover) |
|
|
| [[raw/branch-notes/feature-runtime-health-lifecycle-contract]] | required vs optional dependency SSOT 의 boolean 시맨틱 (`@ConditionalOnBooleanProperty` 3.5.0+ 정합성) |
|
|
| [[raw/branch-notes/feature-skeleton-package-blueprint-contract]] | adapter 후보 package 의 AutoConfiguration import 등록 위치 (`META-INF/spring/...AutoConfiguration.imports`) 결정 |
|
|
|
|
## 컨텍스트 / 왜 저장했는지
|
|
|
|
ca-tmpl `feature-integration-adapter-templates` branch의 **결정 근거 (canonical reference)**. branch는 "optional adapter는 `@ConditionalOnProperty(name="app.adapter.{adapterName}.enabled", havingValue="true")` 적용"을 결정. 이 결정의 정확한 공식 시맨틱과 대안(`@AutoConfiguration` without `ConditionalOnProperty`, `@Profile`)과의 차이를 명확히 보존.
|
|
|
|
## 출처 / Source
|
|
|
|
- 원본 URL: https://docs.spring.io/spring-boot/reference/features/developing-auto-configuration.html
|
|
- 보조 URL: https://docs.spring.io/spring-boot/3.5/api/java/org/springframework/boot/autoconfigure/condition/ConditionalOnProperty.html
|
|
- 보조 URL: https://docs.spring.io/spring-boot/3.5/api/java/org/springframework/boot/autoconfigure/condition/ConditionalOnBooleanProperty.html
|
|
- 아카이브 URL: (미수집)
|
|
- 저자 / 조직: Spring Team (spring-projects)
|
|
- 발행 상태: Spring Boot 3.5 GA (Java 21 baseline), `@ConditionalOnBooleanProperty` since 3.5.0
|
|
- 마지막 확인일: 2026-05-27
|
|
|
|
## 핵심 인용 / Key quotes (verbatim)
|
|
|
|
> [§Understanding Auto-configured Beans] "Classes that implement auto-configuration are annotated with `@AutoConfiguration`. This annotation itself is meta-annotated with `@Configuration`, making auto-configurations standard `@Configuration` classes. Additional `@Conditional` annotations are used to constrain when the auto-configuration should apply. Usually, auto-configuration classes use `@ConditionalOnClass` and `@ConditionalOnMissingBean` annotations. This ensures that auto-configuration applies only when relevant classes are found and when you have not declared your own `@Configuration`."
|
|
|
|
> [§Locating Auto-configuration Candidates] "Spring Boot checks for the presence of a `META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports` file within your published jar. The file should list your configuration classes, with one class name per line." (additional: "Auto-configurations must be loaded _only_ by being named in the imports file. Make sure that they are defined in a specific package space and that they are never the target of component scanning.")
|
|
|
|
> [§`@ConditionalOnProperty` Javadoc] "`@Conditional` that checks if the specified properties have a specific value. By default the properties must be present in the `Environment` and not equal to `false`." (collection note: "This condition cannot be reliably used for matching collection properties... It is better to use a custom condition for such cases.")
|
|
|
|
> [§`@ConditionalOnBooleanProperty` Javadoc, since 3.5.0] "`@Conditional` annotation that checks if the specified properties have a specific boolean value. By default the properties must be present in the `Environment` and equal to `true`. The `havingValue()` and `matchIfMissing()` attributes allow further customizations."
|
|
|
|
> [§Naming + Configuration keys] "Do not start your module names with `spring-boot`, even if you use a different Maven `groupId`." / "If your starter provides configuration keys, use a unique namespace for them. In particular, do not include your keys in the namespaces that Spring Boot uses (such as `server`, `management`, `spring`, and so on)... As a rule of thumb, prefix all your keys with a namespace that you own (for example `acme`)."
|
|
|
|
## Claims Extracted / 추출된 주장
|
|
|
|
| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove |
|
|
|---|---|---|---|---|---|
|
|
| SBAC-C1 | auto-configuration class 는 `@AutoConfiguration` (= meta-annotated `@Configuration`) + 추가 `@Conditional` (보통 `@ConditionalOnClass`, `@ConditionalOnMissingBean`) 로 적용 조건을 제한 | [§Understanding Auto-configured Beans] "Classes that implement auto-configuration are annotated with `@AutoConfiguration`. This annotation itself is meta-annotated with `@Configuration`... Additional `@Conditional` annotations are used to constrain when the auto-configuration should apply. Usually, auto-configuration classes use `@ConditionalOnClass` and `@ConditionalOnMissingBean` annotations." | `official-vendor-doc` | Spring Boot AutoConfiguration 작성 일반 | `@ConditionalOnProperty` 가 표준 권장 조합이라는 뜻은 아님 (문서가 명시한 표준 조합은 OnClass + OnMissingBean) |
|
|
| SBAC-C2 | auto-configuration discovery 는 published jar 의 `META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports` 파일에 한 줄당 한 class FQN 을 나열하는 방식이며, **imports file 에 등록되지 않은 class 는 auto-configuration 으로 로드되지 않음** + component scan 대상이 되면 안 됨 | [§Locating Auto-configuration Candidates] "Spring Boot checks for the presence of a `META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports` file... The file should list your configuration classes, with one class name per line." + "Auto-configurations must be loaded _only_ by being named in the imports file." | `official-vendor-doc` | Spring Boot 2.7+ 의 `AutoConfiguration.imports` 메커니즘 | 기존 `spring.factories` 가 deprecated 라는 뜻은 본 인용 범위 밖 (별도 release note) |
|
|
| SBAC-C3 | `@ConditionalOnProperty` 는 default 로 property 가 Environment 에 **존재** + 값이 **`false` 가 아닐 때** 매칭. `matchIfMissing` default 는 `false`. **collection property 에는 신뢰성 있게 사용 불가** | [§`@ConditionalOnProperty` Javadoc] "By default the properties must be present in the `Environment` and not equal to `false`." + "This condition cannot be reliably used for matching collection properties... It is better to use a custom condition for such cases." | `official-reference` | Spring Boot 3.x `@ConditionalOnProperty` 사용 | `havingValue` 미지정 시 모든 임의 string 값에 매칭한다는 뜻은 아님 — 명시적으로 `false` 만 reject, 빈 string 은 표 참조 |
|
|
| SBAC-C4 | `@ConditionalOnBooleanProperty` (since 3.5.0) 는 boolean 시맨틱을 명시적으로 강제 — default 로 property 가 Environment 에 **존재** + 값이 **`true`** 일 때 매칭, `matchIfMissing` default `false` | [§`@ConditionalOnBooleanProperty` Javadoc, since 3.5.0] "By default the properties must be present in the `Environment` and equal to `true`. The `havingValue()` and `matchIfMissing()` attributes allow further customizations." | `official-reference` | Spring Boot 3.5.0+ 환경 | 3.5.0 미만 버전에서 동일 시맨틱이 가능하다는 뜻은 아님 (그 경우 `@ConditionalOnProperty(havingValue="true")` 명시 필요) |
|
|
| SBAC-C5 | starter 의 configuration key 는 **own namespace** prefix 의무. `server`, `management`, `spring` 등 Spring Boot 가 사용하는 namespace 사용 금지 (향후 Spring 이 충돌 변경 가능). module 이름은 `spring-boot` 로 시작 금지 | [§Naming + Configuration keys] "Do not start your module names with `spring-boot`..." + "do not include your keys in the namespaces that Spring Boot uses (such as `server`, `management`, `spring`, and so on)... prefix all your keys with a namespace that you own (for example `acme`)." | `official-vendor-doc` | custom starter 배포 | "acme" 이외의 특정 prefix 가 권장된다는 뜻은 아님 — 본 문서는 예시일 뿐 |
|
|
|
|
## Usage Boundaries / 적용 경계
|
|
|
|
- **이 자료가 직접 증명하는 것**:
|
|
- `SBAC-C1`: `@AutoConfiguration` 의 메타 구조 + 표준 `@Conditional` 조합 (`OnClass` + `OnMissingBean`)
|
|
- `SBAC-C2`: `AutoConfiguration.imports` 파일 위치·형식·discovery 의무
|
|
- `SBAC-C3`: `@ConditionalOnProperty` 의 default 매칭 규칙 + collection 한계
|
|
- `SBAC-C4`: `@ConditionalOnBooleanProperty` (3.5.0+) 의 명시적 boolean 시맨틱
|
|
- `SBAC-C5`: custom starter 의 namespace/naming 의무
|
|
- **이 자료가 증명하지 않는 것**:
|
|
- "ApplicationContext bean count = 0" 검증이 Spring 공식 권장 verification 패턴이라는 명제 (본 문서는 verification 메커니즘을 명시 안 함)
|
|
- ArchUnit 기반 정적 검사가 Spring 공식 권장 패턴이라는 명제 (Spring docs 범위 밖)
|
|
- `AdapterDisabledException` 같은 runtime fail-fast 패턴 (ca-tmpl 자체 contract, 공식 문서 부재)
|
|
- `@Profile` 과 `@ConditionalOnProperty` 의 정확한 우선순위·결합 시맨틱
|
|
- **내 프로젝트(ca-tmpl) 에 적용하려면 추가 확인이 필요한 것**:
|
|
- `havingValue="true"` 명시 + `matchIfMissing=false` 조합이 branch 의 "기본 disabled" 의도를 정확히 표현하는지 (intent 일치 확인)
|
|
- 3.5.0 미만 baseline 인 경우 `@ConditionalOnBooleanProperty` 사용 불가 → fallback 필요
|
|
- starter 의 `acme` 같은 prefix 를 ca-tmpl 의 `app.adapter.<name>.enabled` 네임스페이스로 매핑하는 결정 (본 문서는 prefix 예시만 제공)
|
|
|
|
## 메모 / Notes (내 프로젝트 해석 — 미검증)
|
|
|
|
> 본 섹션은 자료 직접 인용 아님. ca-tmpl 결정 컨텍스트 해석.
|
|
|
|
- 적용 시나리오: 선택형 adapter (Kafka / Redis / Slack / Google Email) 같은 외부 통합 모듈을 단일 codebase에 두되, application property로 on/off 전환.
|
|
- 장점:
|
|
- **표준 메커니즘**: `@ConditionalOnProperty` + `AutoConfiguration.imports` 조합은 Spring 공식 패턴.
|
|
- **boot 시점 결정**: false → bean 자체 등록 안 됨. ApplicationContext 검사로 검증 가능.
|
|
- branch가 결정한 **3-layer detection (ApplicationContext / ArchUnit / Runtime AdapterDisabledException)** 중 Layer 1을 정확히 cover.
|
|
- Spring Boot 3.5부터 `@ConditionalOnBooleanProperty` 추가 — boolean 시맨틱이 명시적으로 강제됨. branch의 "boolean true/false only" 결정과 정합.
|
|
- 단점 / 함정:
|
|
- `havingValue` 누락 시: property가 단순히 "존재"하면 매칭 → false 의도가 무력화될 수 있음. branch는 `havingValue="true"` 명시.
|
|
- `matchIfMissing`은 default false. 누락된 env가 자동으로 enable로 해석되지 않도록 주의.
|
|
- collection property에는 사용 부적합 (Javadoc 명시).
|
|
- ca-tmpl 결정과의 매핑:
|
|
- branch Layer 1: `@ConditionalOnProperty(name="app.adapter.{name}.enabled", havingValue="true")` → 본 문서 인용 그대로.
|
|
- branch Layer 2 (ArchUnit `noClasses().that().resideInAPackage("..application..").should().dependOnClassesThat().resideInAPackage("..adapters.{disabled-adapter}..")`): Spring 공식 문서 범위 밖. ArchUnit 별도 source 필요.
|
|
- branch Layer 3 (`AdapterDisabledException` + log code `REQUIRED_ADAPTER_DISABLED`): branch 자체 contract. 공식 문서가 강제하지 않는 영역.
|
|
- 대안 비교:
|
|
- `@Profile("kafka")` — boolean 시맨틱 부재, 다중 활성/비활성 표현이 어려움.
|
|
- `AutoConfiguration` without ConditionalOnProperty — classpath 존재만으로 bean 등록 → 비활성 의도 표현 불가.
|
|
- SPI/ServiceLoader — Spring DI와 별도 라이프사이클. Spring 환경에서는 over-engineering.
|
|
- 신뢰도: `official-doc` 등급. Spring 공식 reference + API doc.
|
|
|
|
## Related / 관련
|
|
|
|
- 같은 주제 다른 official-doc:
|
|
- [[raw/official-docs/adapter-java-spi-serviceloader]] (대안 4 — Java 표준 SPI)
|
|
- [[raw/official-docs/archunit-conditional-on-property-3-layer-pattern]] (Layer 2 ArchUnit 정적 검사 한계 평가)
|
|
- [[raw/official-docs/governance-archunit-official]] (ArchUnit fitness function 일반)
|
|
- 인용하는 branch:
|
|
- [[raw/branch-notes/feature-integration-adapter-templates]]
|
|
- [[raw/branch-notes/feature-architecture-enforcement-rules]]
|
|
- [[raw/branch-notes/feature-runtime-health-lifecycle-contract]]
|
|
- [[raw/branch-notes/feature-skeleton-package-blueprint-contract]]
|
|
- 대안 그룹: **Group I — Integration adapter templates** (대안 5종: Spring Boot AutoConfiguration / Plugin architecture OSGi-style / `@Profile` / Java SPI / FF4J·Togglz)
|
|
- 본 source의 위치: **대안 1: Spring Boot AutoConfiguration + `@ConditionalOnProperty` (branch의 채택안)**
|
|
- 인용하는 wiki: (미작성)
|