Files
llm-wiki/raw/official-docs/adapter-java-spi-serviceloader.md
T

10 KiB

title, source_type, url, archive_url, status, confidence, related_branches, related_projects, tags, created, last_reviewed
title source_type url archive_url status confidence related_branches related_projects tags created last_reviewed
Java SPI (Service Provider Interface) + ServiceLoader — adapter 대안 official-doc https://docs.oracle.com/javase/tutorial/ext/basics/spi.html raw high
feature-integration-adapter-templates
feature-skeleton-package-blueprint-contract
ca-tmpl
ca-tmpl
adapter
java
spi
serviceloader
plugin
alternative
2026-05-22 2026-05-27

Java SPI (Service Provider Interface) + ServiceLoader — adapter 대안

Layer: raw/official-docs/ — Oracle Java Tutorial "Creating Extensible Applications" 의 SPI/ServiceLoader 발췌. ca-tmpl feature-integration-adapter-templates branch의 adapter on/off 메커니즘 대안 4 (Java 표준 plugin architecture) 근거.

Parent / 활용 branch (필수)

Branch 이 자료가 정당화하는 결정
raw/branch-notes/feature-integration-adapter-templates Group G-I 대안 4 (Java SPI / ServiceLoader plugin architecture) 의 시맨틱·한계 — Spring @ConditionalOnProperty 채택 결정의 비교 기준
raw/branch-notes/feature-skeleton-package-blueprint-contract adapter 후보 package 설계 시 "Spring DI vs classpath SPI" 분기 검토 근거

컨텍스트 / 왜 저장했는지

ca-tmpl feature-integration-adapter-templates branch의 대안 4. branch는 Spring @ConditionalOnProperty 기반 optional module을 채택했음. 대안으로 Java 표준 SPI (ServiceLoader)가 있는데, 둘의 시맨틱 차이를 명확히 보존.

출처 / Source

핵심 인용 / Key quotes (verbatim)

[§Service Provider Interface (SPI) 정의] "The set of public interfaces and abstract classes that a service defines. The SPI defines the classes and methods available to your application."

[§ServiceLoader 역할] "The java.util.ServiceLoader class helps you find, load, and use service providers. It searches for service providers on your application's class path or in your runtime environment's extensions directory. It loads them and enables your application to use the provider's APIs."

[§META-INF/services 등록] "To register your service provider, you create a provider configuration file, which is stored in the META-INF/services directory of the service provider's JAR file. The name of the configuration file is the fully qualified class name of the service provider, in which each component of the name is separated by a period (.), and nested classes are separated by a dollar sign ($)."

[§Lazy instantiation + caching] "Providers are located and instantiated on demand. A service loader maintains a cache of the providers that were loaded. Each invocation of the loader's iterator method returns an iterator that first yields all of the elements of the cache, in instantiation order. The service loader then locates and instantiates any new providers, adding each one to the cache in turn. You can clear the provider cache with the reload method."

[§Default constructor 요구] "The ServiceLoader class requires that the single exposed provider type has a default constructor, which requires no arguments. This enables the ServiceLoader class to easily instantiate the service providers that it finds."

Claims Extracted / 추출된 주장

Claim ID Claim (이 자료가 직접 말하는 것) Evidence quote Strength Applies to Does not prove
SPI-C1 SPI 는 service 가 정의하는 public interfaces + abstract classes 집합으로, application 이 사용할 수 있는 classes/methods 를 정의 [§Service Provider Interface (SPI) 정의] "The set of public interfaces and abstract classes that a service defines. The SPI defines the classes and methods available to your application." official-vendor-doc Java SE SPI 패턴 일반 SPI 가 on/off 토글 메커니즘을 포함한다는 뜻은 아님 — provider 등록 = 자동 활성
SPI-C2 ServiceLoader 는 application classpath 또는 runtime extensions directory 에서 service provider 를 검색·로드하여 application 에 노출 [§ServiceLoader 역할] "It searches for service providers on your application's class path or in your runtime environment's extensions directory. It loads them and enables your application to use the provider's APIs." official-vendor-doc classpath 기반 plugin discovery 시나리오 property/env 기반 활성 제어 메커니즘이 있다는 뜻은 아님 (classpath 존재 = 활성)
SPI-C3 provider 등록은 JAR 의 META-INF/services/ 디렉토리에 fully qualified service interface name 의 파일을 두고, 각 줄에 provider FQN 을 나열하는 방식 [§META-INF/services 등록] "To register your service provider, you create a provider configuration file, which is stored in the META-INF/services directory of the service provider's JAR file. The name of the configuration file is the fully qualified class name of the service provider" official-vendor-doc JAR-packaged provider 배포 YAML/property 기반 등록이나 Spring application.yml 통합이 가능하다는 뜻은 아님
SPI-C4 provider 는 on-demand instantiate 되며 ServiceLoader 는 캐시를 유지, iterator() 호출 시 캐시된 provider 부터 instantiation order 로 yield, reload() 로 캐시 비우기 가능 [§Lazy instantiation + caching] "Providers are located and instantiated on demand. A service loader maintains a cache of the providers that were loaded. Each invocation of the loader's iterator method returns an iterator that first yields all of the elements of the cache, in instantiation order... You can clear the provider cache with the reload method." official-vendor-doc 단일 ServiceLoader 인스턴스의 라이프사이클 "lazy" 가 모든 provider 의 instantiate 비용을 0 으로 만든다는 뜻은 아님 — 첫 iterate 시 등록된 모든 provider 가 검출됨
SPI-C5 ServiceLoader 는 exposed provider type 에 default (no-arg) constructor 요구 [§Default constructor 요구] "The ServiceLoader class requires that the single exposed provider type has a default constructor, which requires no arguments." official-vendor-doc 표준 ServiceLoader.load() 경로 constructor injection 으로 dependency 주입이 가능하다는 뜻은 아님 (Java 9+ provider() static method 패턴은 별도 문서)

Usage Boundaries / 적용 경계

  • 이 자료가 직접 증명하는 것:
    • SPI-C1: SPI 의 정의 (interface + abstract class 집합)
    • SPI-C2: ServiceLoader 의 검색 경로 (classpath / extensions dir)
    • SPI-C3: META-INF/services/<FQN> 파일 형식 의무
    • SPI-C4: lazy instantiation + 캐시 + reload() 시맨틱
    • SPI-C5: provider 의 default constructor 강제 요구
  • 이 자료가 증명하지 않는 것:
    • SPI 가 property/env 기반 on/off 제어를 지원한다는 명제 (classpath 존재 = 활성, 본 인용 범위에서 disable 메커니즘 부재)
    • Spring DI 컨테이너와의 통합 (Spring @Autowired/@Transactional 이 SPI provider 에 적용된다는 보장 없음)
    • JPMS (Java 9+) provides ... with ... 선언과의 정확한 통합 시맨틱 (별도 JPMS 문서 필요)
    • 검출 시점이 Spring ApplicationContext 시작 시점과 어떻게 정렬되는지
  • 내 프로젝트(ca-tmpl) 에 적용하려면 추가 확인이 필요한 것:
    • ConditionalOnProperty 처럼 "기본 disabled + property 로 enable" 시맨틱을 SPI 로 표현하려면 별도 wrapper layer 가 필요 (본 문서로 보장 안 됨)
    • branch 의 "Layer 1 ApplicationContext bean count = 0" 검증을 SPI provider 에 적용할 수 없음 — SPI provider 는 Spring bean 이 아니므로 별도 검증 메커니즘 필요

메모 / Notes (내 프로젝트 해석 — 미검증)

본 섹션은 자료 직접 인용 아님. ca-tmpl 결정 컨텍스트 해석.

  • 적용 시나리오: 프레임워크 / 라이브러리 작성자 입장에서 사용자가 외부 jar drop-in으로 기능 확장하게 하고 싶을 때 (JDBC Driver, SLF4J binding, JPA provider, Spring Boot SpringApplicationRunListener 등 실제로 사용 중).
  • 장점:
    • 표준 JDK: 의존성 없음. ClassLoader 수준 작동.
    • classpath drop-in: jar만 넣으면 META-INF/services/ 자동 감지.
    • JPMS (Java 9+) provides ... with ... 선언과 통합.
  • 단점 / ca-tmpl 적용 시 한계:
    • on/off 제어가 없음: classpath에 존재하면 즉시 provider로 등록. branch가 요구한 "disabled state 기본값"을 표현할 표준 메커니즘이 없음. property 기반 게이팅이 SPI에는 없음.
    • DI 통합 없음: ServiceLoader가 instantiate하는 객체는 Spring bean이 아님. @Autowired, @Transactional 등 Spring 기능 미적용. wrapping이 별도로 필요.
    • default constructor 강제: 의존 주입을 생성자로 받을 수 없음.
    • 검출 비용: provider 검색이 lazy하지만 한 번 트리거되면 모든 provider iterate.
    • branch Layer 1 검증 (ApplicationContext bean count = 0) 불가능: bean이 애초에 ApplicationContext에 없음. 검증 메커니즘을 별도로 짜야 함.
  • ca-tmpl 결정과의 차이:
    • ca-tmpl: Spring DI + @ConditionalOnProperty 1차. ApplicationContext bean 등록 여부로 enable/disable 검증.
    • SPI: classpath 기반 자동 발견. enable/disable이 jar inclusion/exclusion으로만 표현됨 (= build artifact 분리). branch의 "build artifact 1개 + env 주입" 결정과 충돌.
  • 채택 시점 후보: 프레임워크 자체를 만들 때, 또는 third-party가 plugin을 작성하게 해야 할 때. application 내부 adapter on/off에는 부적합.
  • 신뢰도: official-doc 등급. Oracle Java Tutorial + JDK API doc.