Spring Framework 7.1.0-SNAPSHOT 기준 해설
spring-core는 Spring 전체가 딛고 서는 기반 모듈이다. 자원(Resource) 추상화, 타입 변환(Conversion), 실행 환경(Environment)/프로퍼티, 어노테이션 메타데이터, 제네릭 타입 해석(ResolvableType), 그리고 재패키징된 바이트코드 라이브러리(ASM/CGLIB/Objenesis)와 광범위한 유틸리티를 제공한다.
애플리케이션을 조립하는 컨테이너(spring-beans, spring-context)는 다음과 같은 "공통적이고 저수준인" 능력을 필요로 한다.
- "어디서든 무언가를 읽어와야 한다" — 클래스패스, 파일시스템, URL, JAR 안의 리소스를 동일한 인터페이스(
Resource)로 다룬다. - "문자열을 타입으로 바꿔야 한다" —
"true"→boolean,"1,2,3"→List<Integer>같은 변환을 일관된 SPI(ConversionService)로 처리한다. - "실행 환경마다 다른 설정 값을 읽어야 한다" — 시스템 프로퍼티, 환경 변수,
.properties를 우선순위로 묶고${...}치환과 프로파일을 제공한다(Environment). - "클래스를 로드하지 않고 어노테이션을 읽어야 한다" — 컴포넌트 스캔을 위해 ASM으로 바이트코드를 파싱해 메타데이터를 얻는다(
MetadataReader,MergedAnnotations). - "제네릭/프록시/리플렉션을 다뤄야 한다" —
ResolvableType,MethodParameter, CGLIB 프록시 생성 등.
spring-core는 이 모든 것을 다른 Spring 모듈에 의존하지 않고 자급한다. 그래서 의존성 그래프의 가장 아래에 위치한다.
(이 모듈을 의존하는 쪽 / 위로 갈수록 상위)
┌──────────────────────────────────────────────┐
│ spring-context · spring-web · spring-tx · … │
└──────────────────────────────────────────────┘
│ 의존
┌──────────────────────────────────────────────┐
│ spring-beans │
└──────────────────────────────────────────────┘
│ 의존
┌──────────────────────────────────────────────┐
│ spring-core ◀── 지금 이 모듈 │
└──────────────────────────────────────────────┘
│ 의존
┌──────────────────────────────────────────────┐
│ spring-jcl (로깅 브리지) + JDK │
└──────────────────────────────────────────────┘
- 의존하는 모듈: 사실상
spring-jcl(commons-logging 브리지)과 JDK뿐이다. Reactor/RxJava/Kotlin 등은 모두 선택적(optional) 으로, 클래스패스에 있으면 활성화된다. - 의존받는 모듈: 거의 모든 Spring 모듈.
spring-beans가 직접 위에 올라타고, 그 위로 전체 생태계가 쌓인다.
- 01-resource-자원-추상화.md —
Resource/ResourceLoader로 모든 입력을 통일하는 자원 추상화 계층. - 02-타입-변환-conversion.md —
ConversionService와 Converter SPI,TypeDescriptor기반 타입 변환 시스템. - 03-environment-와-propertysource.md —
Environment,PropertySource, 프로파일과${...}플레이스홀더. - 04-타입-리플렉션과-제네릭.md —
ResolvableType,MethodParameter, 순서(Ordered)와 파라미터 이름 발견. - 05-어노테이션-메타데이터와-asm.md —
MergedAnnotations,@AliasFor, ASM 기반MetadataReader로 클래스 로딩 없이 메타데이터 읽기. - 06-바이트코드-재패키징-cglib-asm-objenesis.md — 재패키징된 ASM/CGLIB/Objenesis가 왜 여기 있고 어떻게 쓰이는가.
- 07-유틸리티와-부가-인프라.md —
util유틸리티 군, 리액티브 어댑터, 태스크/재시도,SpringFactoriesLoader, AOT 힌트.
org.springframework
│
├── core ── 모듈의 심장. 핵심 추상화 + 인프라
│ ├── (root) ResolvableType, MethodParameter,
│ │ Ordered/OrderComparator,
│ │ ReactiveAdapterRegistry, SpringVersion …
│ ├── io Resource / ResourceLoader 자원 추상화
│ │ └── support PathMatchingResourcePatternResolver,
│ │ SpringFactoriesLoader, EncodedResource …
│ ├── convert 타입 변환 SPI (ConversionService)
│ │ ├── converter Converter / GenericConverter / Factory
│ │ └── support GenericConversionService + 기본 변환기들
│ ├── env Environment / PropertySource / Profiles
│ ├── annotation MergedAnnotations, @AliasFor, @Order
│ ├── type ClassMetadata / AnnotationMetadata
│ │ ├── classreading ASM 기반 MetadataReader
│ │ └── filter TypeFilter (컴포넌트 스캔 매칭)
│ ├── codec Encoder / Decoder (리액티브 직렬화)
│ ├── serializer Serializer / Deserializer (단순 직렬화)
│ ├── task TaskExecutor (SimpleAsync, VirtualThread)
│ ├── retry RetryTemplate / RetryPolicy (7.0+)
│ ├── style ToStringCreator 등 표현 유틸
│ ├── log LogMessage 지연 로깅 헬퍼
│ └── metrics ApplicationStartup 시작 단계 계측
│
├── util ── 범용 유틸리티 (의존 없는 toolbox)
│ ├── (root) StringUtils, ClassUtils, ObjectUtils,
│ │ ReflectionUtils, CollectionUtils,
│ │ AntPathMatcher, ConcurrentReferenceHashMap …
│ ├── concurrent ListenableFuture 계열 동시성 유틸
│ ├── function SingletonSupplier 등 함수형 유틸
│ ├── comparator Comparator 조합 도구
│ ├── backoff BackOff 전략
│ ├── unit DataSize 등 단위
│ └── xml StAX/SAX XML 유틸
│
├── aot ── Ahead-Of-Time / 네이티브 이미지 지원
│ ├── hint RuntimeHints (리플렉션/리소스/프록시 등록)
│ ├── generate 생성 코드 관리(GeneratedFiles 등)
│ └── nativex GraalVM native-image 통합
│
├── asm (재패키징) ── ObjectWeb ASM: 바이트코드 읽기/쓰기
├── cglib (재패키징) ── CGLIB: 런타임 서브클래스 프록시
├── objenesis (재패키징) ── Objenesis: 생성자 없는 인스턴스화
├── javapoet (재패키징) ── JavaPoet: 소스 코드 생성(AOT용)
│
└── lang ── @Nullable/@Contract 등 보조 어노테이션
참고:
asm,cglib,objenesis,javapoet는 외부 라이브러리를org.springframework.*네임스페이스로 재패키징(shade) 한 것이다. 버전 충돌을 피하고 내부 전용으로 쓰기 위함이며, 자세한 배경은 6장에서 다룬다.