스터디/[토비의 스프링 3.1 Vol 1] (2025.03)

[토비의 스프링 3.1 Vol 1] 8장. 스프링이란 무엇인가?

ttoance 2025. 6. 8. 10:00
반응형

8.1 스프링의 정의

  • 스프링에 대해 가장 잘 알려진 정의는 이렇다.
    • "자바 엔터프라이즈 개발을 편하게 해주는 오픈소스 경량급 애플리케이션 프레임워크"
  • 애플리케이션 프레임워크 
    • 일반적으로 프레임워크는 애플리케이션의 특정 계층에서 주로 동작하는 한 가지 기술 분야에 집중된다. 
    • 애플리케이션 프레임워크는 특정 계층이나 기술, 업무 분야에 국한되지 않고 애플리케이션의 전 영역을 포괄하는 범용적인 프레임워크를 말한다. 목표는 애플리케이션 개발의 전 과정을 빠르고 편리하며 효율적으로 진행하는 데 있다. 
    • 스프링이 애플리케이션 프레임워크라고 불리는 이유는 애플리케이션의 전 영역을 관통하는 일관된 프로그래밍 모델과 핵심 기술을 바탕으로 해서 각 분야의 특성에 맞는 필요를 채워주고 있어 애플리케이션을 빠르고 효과적으로 개발할 수 있기 때문이다. 
  • 경량급
    • 스프링의 기원이 된 책에서 비판하는 자바 엔터프라이즈 기술의 불필요한 복잡함에 반대되는 개념이다.  
    • 당시 EJB 는 기술에 대한 욕심으로 개발환경과 운영서버, 개발과 빌드, 테스트 과정, 작성된 코드 모두 무겁고 복잡하게 만들었다.
    • EJB가 동작하려면 무거운 자바 서버 WAS가 필요했고, 툴의 도움 없이는 설정파일구조가 까다롭고, 패키징/불편한 서버 배포등으로 인해 고자 제품으로 구성된 제대로 된 개발환경 없이는 개발하기가 힘들었다. 
    • 그에 비해 스프링은 가장 단순한 서버환경인 톰캣이나 제티에서도 완벽하게 동작한다. 
    • 만들어진 코드가 지원하는 기술수준은 비슷하더라도 그것을 훨씬 빠르고 간편하게 작성하게 해줌으로써 생산성과 품질면에서 유리하다는 측면에서 경량급이라고 표현한다. 
  • 자바 엔터프라이즈 개발을 편하게 해주는 
    • 스프링은 근본적인 문제점에 도전해서 해결책을 제시한다는 것이 기존 기술의 접근 방법과 스프링의 접근 방법의 차이점이다. 
    • 편리한 애플리케이션 개발이란 개발자가 복잡하고 실수하기 쉬운 로우레벨 기술에 많은 신경 쓰지 않으면서도 애플리케이션의 핵심인 사용자의 요구사항, 즉 비즈니스 로직을 빠르고 효과적으로 구현하는 것을 말한다. 
  • 오픈소스
    • 스프링은 오픈소스 프로젝트 방식으로 개발돼왔다. 
    • 스프링의 개발 과정은 공개되어 있지만 공식적인 개발은 제한된 인원의 개발자에 한정된다. 
    • 장점은 공개된 커뮤니티의 공간 안에서 투명한 방식으로 다양한 참여를 통해 개발되기 때문에 매우 빠르고 유연한 개발이 가능하다. 
    • 오픈소스 개발의 단점은 지속적이고 안정적인 개발이 계속될지가 불확실하다는 것이다. 
    • 스프링은 오픈소스 개발이라는 방법은 선택했지만 프레임워크 사용자에게 지속적인 신뢰를 줄 수 있도록 개발을 책임지고 진행할 수 있는 전문 기업을 만들었다. 

 

8.2 스프링의 목적 

8.2.1 엔터프라이즈 개발의 복잡함

 

복잡함의 근본적인 이유

  • 기술적인 제약조건과 요구사항이 늘어나기 때문이다. 
    • 엔터프라이즈 시스템이란 서버에서 동작하며 기업과 조직의 업무를 처리해주는 시스템을 말한다. 
    • 엔터프라이즈 시스템이 기업 업무를 처리하는데 핵심적인 역할로 등장하고 중요해지면서 점점 더 기술적인 요구는 심화되고 복잡도는 증가한다. 
  • 엔터프라이즈 애플리케이션이 구현해야 할 핵심기능인 비즈니스 로직의 복잡함이 증가하기 때문이다. 
    • 다양하고 복잡한 업무 처리 기능을 엔터프라이즈 시스템이 구현해야 했다. 
    • 다양한 예외상황도 많고 처리해야 하는 정보의 규모도 상당하다. 

 

복잡함을 가중시키는 원인 

  • 엔터프라이즈 애플리케이션 개발이 실패하는 주요 원인은 비즈니스 로직의 복잡함과 기술적인 복잡함이다. 
  • 복잡하다는 건 단지 양이 많고 어렵다는 뜻이 아니다. 세부 요소들이 이해하기 힘든 방식으로 얽혀 있고, 그 때문에 더 다루기 어렵다는 의미이다. 
  • 전통적인 자바 엔터프라이즈 개발 기법은 대부분 비즈니스 로직의 복잡한 구현 코드와 엔터프라이즈 서비스 이용하는 기술적인 코드가 혼재될 수 밖에 없는 방식이라 개발자가 동시에 그 두가지 모두 신경 써서 개발해야 했다. 

 

8.2.2 복잡함을 해결하려는 도전 

 

제거될 수 없는 근본적인 복잡함 

  • 물론 구현해야 할 비즈니스 로직의 적용범위를 줄이고, 기술적인 요구조건 일부 생략하면 그만큼 개발이 편해지고 실패하지 않겠지만 현실적으로 불가능하다. 
  • 기술적인 복잡함 해결하고자 보안 취약하게 방치한다거나, 사용자가 늘어나도 확장 불가능한 시스템을 만들 수 없다. 
  • 근본적으로 엔터프라이즈 개발에 나타나는 복잡함의 원인은 제거 대상이 아니고 대신 그 복잡함을 효과적으로 상대할 수 있는 전략이 필요하다. 

 

실패한 해결책 : EJB 

  • EJB의 기본 전략은 기술적인 복잡함과 비즈니스 로직의 복잡함을 분리하는 것이었다. 
  • EJB는 기술적인 복잡함을 애플리케이셔느이 핵심 로직에서 일부분 분리하는데는 성공했다. 
  • 반면에 EJB환경에서 동작하기 위해 특정 인터페이스 구현하고, 특정 클래스 상속하고, 서버에 종속적인 서비스 통해서만 접근하고 사용이 가능하게 만든 접근이 잘못되었다. 
  • EJB라는 툴 안에 자바 코드를 만들게 강제함으로써 자바가 원래 갖고 있던 장점을 잃어버렸다. 

 

비침투적인 방식을 통한 효과적인 해결책: 스프링

  • EJB와 동일하게 기술적인 복잡함과 비즈니스 로직의 복잡함을 분리하는 것을 목표를 뒀지만 그 과정에서 EJB처럼 개발자의 코드에 난입해서 지저분하고 복잡한 코드를 만들지는 않았다. 
    • EJB처럼 어떤 기술 적용할때 그 기술과 관련된 코드나 규약 등이 등장하는 경우를 침투적인innovasive 기술이라고 한다. 
    • 반면 비침투적인 기술은 기술의 적용 사실이 코드에 직접 반영되지 않는다. 
  • 스프링이 성공할 수 있었던 이유는 비침투적인 기술이라는 전략을 택했기 때문이다. 

 

8.2.3 복잡함을 상대하는 스프링의 전략 

 

기술적 복잡함을 상대하는 전략 

  • 문제1 : 기술에 대한 접근 방식이 일관성이 없고, 특정환경에 종속적이다.
    • 기술과 서버환경의 변화에 대한 스프링의 공략 방법은 서비스 추상화다. 
    • 추상화 통해 로우레벨의 기술 구현 부분을 기술 사용하는 인터페이스 분리하고, 환경과 세부기술에 대한 독립적인 접근 인터페이스를 제공한다. 
  • 문제2 : 기술적인 처리 담당하는 코드가 성격이 다른 코드에 섞여서 등장한다. 
    • 비즈니스 로직 전후로 경계 설정돼야 하는 트랜잭션, 비즈니스 로직에 대한 보안 적용, 계층 사이 주고 받는 데이터의 예외의 일괄 변환이나 로깅이나 감사 기능이 대표적인 예이다. 
    • 이를 해결하는 방식은 AOP이다. 
    • AOP는 최후까지 애플리케이션 로직 담당하는 코드에 남아 있는 기술 관련 코드를 깔끔하게 분리해서 별도의 모듈로 관리하게 해주는 기술이다. 

 

비즈니스와 애플리케이션 로직의 복잡함을 상대하는 전략 

  • 앤터프라이스 시스템 개발의 흐름은 점차로 비즈니스 로직은 애플리케이션 안에서 처리하도록 만드는 추세이다. 
  • DB는 단지 데이터의 영구적인 저장과 복잡한 조건 가진 검색과 같은 자체적으로 특화된 기능에만 활용하고, 데이터 분석하고 가공하고 그에 따라 로직 처리하는 부분은 확장하기 쉽고, 비용도 싼 애플리케이션 서버 쪽으로 이동한다. 

 

핵심도구 : 객체지향과 DI

  • 기술과 비즈니스 로직의 복잡함 해결하는데 스프링이 공통적으로 사용하는 도구가 객체지향이다. 
  • 기술적인 복잡함 효과적으로 다루게 해주는 기법은 모두 DI를 바탕으로 하고 있다. 
    • 서비스 추상화, 템플릿/콜백, AOP와 같은 스프링의 기술은 DI 없이는 존재할 수 없다. 
    • 그리고 DI는 객체지향 설계 기술 없이는 존재의미가 없다. 
  • 비즈니스 로직 자체의 복잡함을 해결하려면 DI 보다는 객체지향 설계 기법이 더 중요하다. 
    • 순수한 비즈니스 로직만을 담고 있는 코드에는 객체지향 분석과 설계에서 나온 도메인 모델을 쉽게 적용할 수 있다. 
    • 객체지향 특성을 잘 살린 설계는 상속과 다형성, 위임을 포함해서 많은 객체지향 디자인 패턴 설계 기법을 잘 녹아들어 갈 수 있따. 

 

8.3 POJO 프로그래밍 

: 스프링의 핵심 개발자들이 함께 쓴 "Professional Spring Framework"는 스프링의 정수는 엔터프라이즈 서비스 기능을 POJO에 제공하는것 이라고 했다. 

 

8.3.1 스프링의 핵심 : POJO

  • 스프링 애플리케이션은 POJO 이용해 만든 애플리케이션 코드와, POJO가 어떻게 관계를 맺고 동작하는지 정의해놓은 설계정보로 구분된다. 
  • DI의 기본 아이디어는 유연하게 확장 가능한 오브젝트 만들어두고 그 관계는 외부에서 다이내믹하게 설정해준다는 것이다. 
  • 스프링의 주요 기술인 IoC/DI, AOP와 PSA Portable Service Abstraction은 애플리케이션을 POJO로 개발할 수 있게 해주는 기능기술이라고 부른다. 

 

8.3.2 POJO란 무엇인가?

: POJO Plain Old Java Object

 

8.3.3 POJO의 조건 

: 다음 세 가지 조건을 충족해야 POJO라고 부를 수 있다. 

  • 특정 규약에 종속되지 않는다. 
  • 특정 환경에 종속되지 않는다. 
  • 객제지향적인 원리에 충실해야 한다. 

8.3.4 POJO의 장점 

  • 특정한기술과 환경에 종속되지 않아 깔끔한 코드가 될 수 있다. 
    • 로우레벨의 기술과 환경에 종속적인 코드는 비즈니스 로직과 함께 나오면 복잡한 코드가 된다. 
  • POJO로 개발된 코드는 자동화된 테스트에 유리하다. 
  • 객체지향적인 설계를 자유롭게 적용할 수 있다.

 

8.3.5 POJO 프레임워크

  • 스프링은 POJO를 이용한 엔터프라이즈 애플리케이션 개발을 목적으로 하는 프레임워크이다. 
    • 스프링 프레임워크와 하이버네이트는 대표적인 POJO 프레임워크라고 할 수 있다. 

  • 스프링은 비즈니스 로직의 복잡함과 엔터프라이즈 기술의 복잡함을 분리해서 구성할 수 있게 도와준다. 
  • 스프링은 POJO 프레임워크에서 직접 노출하지 않으며서 애플리케이션을 POJO로 쉽게 개발할 수 있게 지원해준다. 

 

8.4 스프링의 기술 

: 스프링에는 POJO 프로그래밍을 손십게 할 수 있도록 지원해주는 세 가지 기능기술을 제공하다. 

  • IoC/DI
  • AOP
  • PSA

 

8.4.1 제어의 역전(IoC) / 의존관계 주입 (DI)

  • IoC/DI는 스프링의 가장 기본이 되는 기술이자 핵심 개발 원칙이다. 
  • 나머지 두 가지 기술인 AOP와 PSA도 IoC/DI에 바탕을 두고 있다. 
  • 3대 기술은 아니지만, 템플릿/콜백 페턴도 IoC/DI가 핵심이다. 
  • (장점) 유연한 확장이 가능하다. DI는 개방 폐쇄 원칙이라는 원칙과 일치하다. 

 

DI의 활용 방법 

핵심 기능의 변경 
  • 예를 들어 서비스 오브젝트가 사용하는 DAO가 있다고 했을 때, DAO의 구현을 JDBC로 했다가, JPA, 하이버네이트 JDO, iBatis 등으로 변경하는 것을 생각할 수 있다. 
핵심 기능의 동적인 변경
  • 동적으로 매번 다르게 변경할 수 있다. 
  • 예를 들어, 사용자의 등급에 따라 다른 DataSource를 사용하게 만들 수 있다. 
  • 또, 사용자 별로 독립적인 의존 오브젝트를 두게 만들 수 있다.
부가 기능의 추가 
  • 대표적인 예는 트랜잭션 추가이다. 
인터페이스의 변경 
  • 사용하려고 하는 오브젝트가 가진 인터페이스가 클라이언트와 호환되지 않을 때, 또는 여러 종류의 인터페이스 가졌지만 비슷한 기능을 담당하는 오브젝트를 바꿔가면서 사용하고 싶을 때 유용하다. 
프록시
  • 필요한 시점에서 실제 사용할 오브젝트 초기화하고 리소스 준비하게 해주는 지연된 로징을 적용한다. 
템플릿과 콜백
  • 반복적으로 등장하지만 항상 고정적인 작업 흐름과 그 사이에서 자주 바뀌는 부분을 분리해서 템플릿과 콜백으로 만들고 이를 DI 원리 응용해 적용하여 간결하게 한다. 
  • 콜백을 만드는 것은 개발을 통한 유연한 확장이고, 템플릿은 한 번 만들어두면 재사용 가능하다는 것이므로 확장에도 변하지 않는다는 OCP 폐쇄 원칙에 맞는다는 점이다. 
싱글톤과 오브젝트 스코프
  • DI를 프레임워크로 사용하게 하여 DI 오브젝트를 컨테이너가 관리하게 한다. 
  • 오브젝트 생성부터 관계설정, 이용, 소멸에 이르는 과정을 DI 컨테이너가 주관하게 한다. 
테스트
  • 오브젝트와 협력해서 등장하는 오브젝트를 고립시켜서 테스트한다. 
  • 의존 오브젝트 대신해서 스텁 또는 목 오브젝트 같은 테스트 대역을 활용한다. 

 

 

8.4.2 애스펙트 지향 프로그래밍 (AOP) 

AOP 적용 기법

  • 스프링과 같이 다이내믹 프록시를 사용한다. 
    • 기존 코드에 영향 주지 않고 부가기능을 적용하게 해주는 데코레이터 패턴을 응용한다. 
    • (단점) 부가기능을 부여할 수 있는 곳은 메소드 호출이 일어나는 지점뿐이다. 
  • 자바 언어 한계 넘어 언어의 확정을 이용한다. 
    • AspectJ라는 오픈소스 AOP 툴을 이용하여 다양한 조인 포인트를 이용해서 AOP를 적용한다. 
    • 자바언어와 JDK 만으로는 불가능하고, 클래스가 메모리로 로딩될 때 그 바이트 코드 조작하는 위빙과 같은 별도의 방법을 이용해야 한다. 
  • 스프링은 프록시 방식의 AOP 기반으로하지만, 필요시 AspectJ를 사용해야 한다. 

 

AOP 적용 단계 

  • 1단계 : 미리 준비된 AOP 사용 
    • 대표적인 AOP는 트랜잭션, @Configurable 애노테이션이 있다. 
  • 2단계 : 전단팀을 통한 정책 AOP 적용 
    • 전체적으로 이용 가능한 것을 소수의 AOP 담당자 관리하에 적용해볼 수 있다. 
    • 이런 기능을 개발자가 직접 추가하려면, 개발 표준이나 가이드라인이 완벽하게 준비되어 있어야 한다. 그러나, 개발자가 실수로 빼먹을 수 있고 엉뚱하게 적용할 수 있다. AOP를 책임지는 소수의 팀만 수고하게 한다 .
  • 3단계 : AOP의 자유로운 이용 
    • 개발자 스스로가 AOP 활용할 수 있게 한다. 

 

8.4.3 포터블 서비스 추상화 (PSA)

  • 환경과 세부 기술 변화에 관계없이 일관된 방식으로 기술에 접근할 수 있게 해주는 PSA Portable Service Abstraction이 있다. 

+) chatgpt 버전 

 

⚙️ PSA의 대표 예시 (Spring 기준)

  • 데이터 접근
    • PSA: JdbcTemplate, JpaRepository
    • 구현체: JDBC, Hibernate, JPA
  • 트랜잭션 처리
    • PSA: PlatformTransactionManager
    • 구현체: JTA, HibernateTransactionManager
  • 메시징
    • PSA: JmsTemplate
    • 구현체: ActiveMQ, RabbitMQ
  • 파일 업로드
    • PSA: MultipartResolver
    • 구현체: Commons FileUpload, Servlet 3.0
  • 캐시 처리
    • PSA: CacheManager
    • 구현체: Ehcache, Redis, Caffeine

 

⚙️ PSA의 원리

  • PSA는 인터페이스나 추상 클래스를 통해 기능을 추상화한다
  • 구현체는 스프링의 의존성 주입을 통해 런타임에 연결된다
  • 코드는 추상 계층만 바라보므로 구현체를 쉽게 바꿀 수 있다
  • 기술 교체, 테스트 환경 전환이 편리해진다
  • 유지보수가 쉬워지고 코드 재사용성과 확장성이 높아진다

 

8.5 정리 

  • 스프링은 그 개발철학과 목표를 분명히 이해하고 사용해야 한다. 
  • 스프링은 오픈소스 소프트웨어이며, 애플리케이션 개발의 모든 기술과 영역을 종합적으로 다루는 애플리케이션 프레임워크다.
  • 엔터프라이즈 애플리케이션 개발의 복잡함은 비즈니스 로직과 엔터프라이즈 시스템의 기술적인 요구에 의해 발생한다. 기존의 접근 방법은 이 복잡도를 낮추지 못하며 자바의 객체지향적인 장점을 포기해야 한다는 문제점이 있다. 
  • 자바의 근본인 객체지향적인 원리에 충실하게 개발할 수 있으며, 환경과 규역에 의존적이지 않은 POJO를 이용한 애플리케이션 개발은 엔터프라이즈 시스템 개발의 복잡함이 주는 많은 문제를 해결할 수 있다. 
  • 스프링의 목적은 이런 POJO를 이용해 엔터프라이즈 애플리케이션을 쉽고 효과적으로 개발할 수 있도록 지원해주는 데 있다. 
  • POJO 방식의 개발을 돕기 위해 스프링은 IoC/DI, AOP, PSA와 같은 기능기술을 프레임워크와 컨테이너라는 방식을 통해 제공한다. 
  •  
반응형