[Spring] spring-core 직접 구현해보기 - (1)

2026. 1. 2. 10:37·spring

https://github.com/ksngh/spring_practice

 

GitHub - ksngh/spring_practice

Contribute to ksngh/spring_practice development by creating an account on GitHub.

github.com

위 링크에 실습으로 작성한 코드가 들어있습니다.

 

STEP 1 - POJO 기반 준비 레이어

STEP 1의 목적은 Spring Core를 배우기 전에 왜 이런 Core 레이어가 필요한 지를 직접 경험해보는 데 있었습니다.

이 단계에서는  Spring을 사용하지 않고 순수 Java(POJO + reflection)만으로 객체를 자동으로 생성하고 운영하려는 코드를 작성했습니다.

그리고 그 과정에서 어디서부터 한계가 발생하는지를 단계별로 확인했습니다.

 

STEP 1 전체에서 작성한 코드는 다음과 같습니다.

  • new 키워드로 직접 의존 객체를 생성하는 POJO 코드
  • reflection을 사용해
    • 생성자 목록을 조회하고
    • 메서드 목록을 조회하고
    • 특정 메서드를 호출하는 코드
  • 객체를 자동으로 생성·실행하려는 간단한 실행기 코드
  • 실행 순서(초기화 → 실행 → 종료)를 보장하려다 실패하는 코드

즉, “프레임워크 흉내를 내는 최소한의 코드”를 직접 만들어 본 단계라고 보시면 됩니다.

STEP 1-1. new 중심 객체 생성의 한계

  • 각 객체가 내부에서 new 키워드로 의존 대상을 직접 생성
  • 예:
    • Service가 Repository를 직접 생성
    • Controller가 Service를 직접 생성

문제 1: 객체가 너무 많은 책임을 가집니다

new를 사용하는 순간, 객체는 다음을 모두 책임지게 됩니다.

  • 어떤 구현체를 사용할지
  • 언제 생성할지
  • 몇 개를 생성할지
  • 생명주기를 어떻게 가져갈지

즉, 객체가 비즈니스 로직뿐 아니라 운영 책임까지 함께 떠안게 됩니다.

문제 2: 객체 그래프가 코드에 박힙니다

A 객체가 내부에서 new B()를 호출하면,

  • A는 B라는 구체 클래스에 강하게 결합됩니다
  • 실행 중에 B를 다른 구현으로 교체하기가 거의 불가능해집니다

이 구조에서는

  • 테스트 시 Mock을 끼우기 어렵고
  • 구조 변경 시 수정 범위가 폭발적으로 늘어납니다

문제 3: 변경이 전파됩니다

의존 대상의 생성자 파라미터가 하나만 바뀌어도, 그 객체를 new 하던 모든 지점을 수정해야 했습니다.

변경의 전파

STEP 1-1 정리

  • new 중심 구조에서는
    • 결합도가 높아지고
    • 테스트가 어려워지고
    • 변경 비용이 급격히 증가합니다
  • 객체 생성과 운영을 중앙에서 관리할 필요성이 드러납니다

STEP 1-2. Reflection으로 자동화를 시도해보기

자동으로 객체를 만들자는 목적의 코드를 작성하였습니다.

  • reflection을 사용해
    • 클래스의 생성자 목록 조회
    • 메서드 목록 조회
    • 특정 생성자나 메서드 호출

STEP 1-1의 문제를 겪은 뒤, reflection으로 클래스 구조를 읽어서 자동으로 생성하면 되지 않을까? 라는 생각이 들었습니다.

그래서 실제로 reflection을 사용해

  • 생성자 배열을 가져오고
  • 메서드 배열을 가져오는 코드를 작성했습니다.

문제 1: 정보는 있는데 기준이 없습니다

reflection은 다음 정보는 잘 제공합니다.

  • 생성자가 몇 개인지
  • 어떤 메서드가 있는지
  • 접근 제어자와 타입 정보

하지만 다음은 확인할 수 없습니다.

  • 어떤 생성자를 선택해야 하는지
  • 어떤 메서드가 초기화용인지
  • 어떤 순서로 실행해야 하는지

즉, 주어진 정보를 활용할 수 없습니다.

문제 2: 판단 로직은 결국 사람이 짜야 합니다

reflection으로 얻은 정보만으로는 실행할 수 없어서,
결국 이런 규칙을 직접 코드로 작성하게 됩니다.

  • “파라미터가 가장 많은 생성자를 쓰자”
  • “이름이 init으로 시작하면 먼저 호출하자”

STEP 1-2 정리

  • reflection은 관측 도구입니다
  • 구조를 실행으로 바꾸기 위해서는 다음과 같은 것들이 필요합니다.
    • 선택 기준
    • 정책
    • 규칙

STEP 1-3. Reflection을 직접 운영 코드에 적용했을 때

이 단계에서 작성한 코드

  • reflection 기반 객체 생성 로직
  • reflection 기반 메서드 호출 로직
  • 예외를 잡기 위한 다수의 try-catch
  • setAccessible(true)를 사용하는 코드

문제 1: 예외 처리가 폭증합니다

reflection API는 구조상 많은 체크 예외를 발생시킵니다.

  • 컴파일 타임에 잡히던 문제가 런타임으로 밀립니다
  • 실제 에러는 InvocationTargetException 안에 감춰집니다

결과적으로

  • 디버깅이 어려워지고
  • 안정성이 떨어집니다

문제 2: 캡슐화가 무너집니다

private 생성자나 메서드를 호출하기 위해 setAccessible(true)를 사용하게 됩니다.

결과적으로, 객체가 스스로 상태를 보호할 수 없게 됩니다.

문제 3: 비즈니스 코드가 오염됩니다

POJO가 순수하게 비즈니스 로직만 담고 있지 못합니다.

어떤 생성자를 쓸지, 어떤 메서드를 언제 호출할지 같은 운영 로직이 스며들기 시작합니다.

STEP 1-3 정리

  • reflection을 직접 굴리기 시작하면
    • 코드가 지저분해지고
    • 규칙이 흩어지고
    • 공통 정책을 만들 수 없게 됩니다

STEP 1-4. 실행 순서 문제와 결정적 한계

이 단계에서 작성한 코드

  • getDeclaredMethods(), getDeclaredConstructors() 사용
  • 반환된 배열을 순서대로 실행하려는 코드
  • 실행 순서가 뒤섞되는 상황을 재현한 코드

문제 1: reflection은 순서를 보장하지 않습니다

실제 시스템에서는

  • 초기화 → 실행 → 종료 같은 흐름이 반드시 존재합니다.

또한

  • A가 준비된 뒤에야 B를 만들 수 있는 의존성 순서가 존재합니다.

하지만 Java reflection API는

  • 반환 순서를 보장하지 않습니다
  • JVM, 컴파일러, 환경에 따라 달라질 수 있습니다

문제 2: 순서 계약을 표현할 언어적 수단이 없습니다

“이 메서드는 먼저 실행해야 한다”라는 의도는

  • 코드나 API에는 표현되어 있지 않습니다

이로 인해

  • 별도의 순서 관리 개념이 필요해집니다

STEP 1 전체 결론 정리

STEP 1을 통해 다음 사실이 명확해졌습니다.

  1. POJO + new 만으로는
    객체 생성, 생명주기, 의존성 관리가 분산되어 통제할 수 없습니다.
  2. reflection은 구조를 보여주지만
    무엇을 어떻게 실행할지는 결정해주지 않습니다.
  3. reflection을 직접 운영에 쓰기 시작하면
    코드 복잡도와 불안정성이 급격히 증가합니다.
  4. 실제 운영에는
    • 생성 정책
    • 실행 순서
    • 생명주기 관리
      가 반드시 필요하지만, Java 표준 API만으로는 이를 표현할 수 없습니다.

'spring' 카테고리의 다른 글

[Spring] spring core 직접 구현해보기 - (2)  (1) 2026.01.23
[Spring] spring-core 직접 구현해보기 - (0)  (5) 2025.12.31
[Spring] 통합 테스트 속도 개선  (2) 2025.12.15
[SNS] 레디스 세션 스토리지를 활용한 인증 인가  (2) 2025.10.01
[spring] 1:1 실시간 채팅 구현  (2) 2025.09.17
'spring' 카테고리의 다른 글
  • [Spring] spring core 직접 구현해보기 - (2)
  • [Spring] spring-core 직접 구현해보기 - (0)
  • [Spring] 통합 테스트 속도 개선
  • [SNS] 레디스 세션 스토리지를 활용한 인증 인가
ksngh
ksngh
웹 백엔드 개발 블로그입니다. https://github.com/ksngh
  • ksngh
    featherdale
    ksngh
  • 전체
    오늘
    어제
    • 분류 전체보기 (66)
      • 데이터베이스 (10)
      • spring (11)
      • redis (7)
      • ELK (11)
      • 회고 (6)
      • 기타 (12)
        • java (2)
        • 디자인패턴 (2)
        • 영어 (1)
        • 자바스크립트 (1)
        • graphQL (2)
        • 블록체인 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Mock
    대용량 데이터 베이스
    elastic search in action
    자료구조
    레디스
    NoriTokenizer
    단위 테스트
    대용량데이터베이스
    PostgreSQL
    Spy
    엘라스틱 서치 인 액션
    Redis
    연말 회고
    조인의 종류
    Spring Core
    core
    Elasticsearch
    spring
    nori tokenizer
    인기검색어 구현
    엘라스틱서치
    gof
    Elastic Search
    NORI
    graphql
    데이터베이스
    엘라스틱 서치
    단위테스트
    디자인패턴
    회고
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
ksngh
[Spring] spring-core 직접 구현해보기 - (1)
상단으로

티스토리툴바