토비 - 8장 스프링이란?

카일·2020년 9월 12일
1

토비의 스프링

목록 보기
6/6
post-thumbnail

스프링의 정의

자바 엔터프라이즈 개발을 편하게 해주는 오픈소스 경량급 애플리케이션 프레임워크

어플리케이션 프레임 워크

라이브러리나 프레임워크는 일반적으로 특정 문제에 대한 불편함을 해소시키고자 등장한다. 하지만 스프링은 어플리케이션 프레임 워크라는 단어를 사용하였다. 이는 어플리케이션 전체에서 발생하는 불편함을 해소하고자 한다는 의미이다. 단순히 많은 영역의 불편함을 커버한다고 어플리케이션 프레임워크라고 칭하지 않는다. 중요한 것은 일관된 가치와 모델을 제시하며 그 가치와 모델을 준수하는 형태로 불편함을 제거해야 한다.

경량급

경량급이라는 말은 불필요하게 무겁지 않다는 의미이다. 제공하는 기능이 다양하기 때문에 코드 라인수는 엄청나게 많다. 하지만 해당 기능을 제공하기 위해서 필요한 최소한의 코드만 포함되어 있다고 생각해도 좋을 것 같다.

자바 엔터프라이즈 개발을 편하게

스프링은 엔터프라이즈 개발의 근본적인 문제를 해결하고자 노력하였다. 어플리케이션을 개발할 땐 아래의 두가지 기술적 문제가 존재하고 이 둘이 합쳐졌을 때 복잡도는 예상하지 못하게 증가한다. 스프링은 이 둘을 분리하기 위해서 로우 레벨의 기술을 분리하고 이를 추상화하여 개발자는 비즈니스 로직에만 집중할 수 있도록 해주었다. 이 과정에서 추가적인 복잡함을 만들어내지 않는 것도 스프링의 장점이다.

  • 기술적인 복잡성 - 로깅 보안 트랜잭션 감사 등
  • 비즈니스 로직의 복잡성

오픈 소스

오픈 소스 프로젝트는 장단점이 존재한다. 빠르고 유연하게 개발되며 많은 피드백을 받고 이를 반영한다. 그리고 라이센스 비용도 없다. 하지만 일반적인 오픈 소스 프로젝트는 지속적이고 안정적인 개발이 불확실하다. 토이 프로젝트로 진행되는 오픈 소스가 대부분이기 때문이다. 하지만 스프링은 오픈 소스의 장점은 가져가면서 전문 담당 팀을 구성하여 관리하고 있다. 즉 지속적이고 안정적인 개발이 불확실한 문제를 해결하면서 오픈 소스의 장점은 가져갈 수 있다.

스프링의 목적

엔터프라이즈 개발의 복잡함을 해소하여, 개발하기 편하게 만들어보자.

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

이유 1. 기술적인 제약조건과 요구사항이 늘어나기 때문이다.

  • 엔터프라이즈 시스템은 많은 사용자의 요청을 동시에 처리해야 하기 때 문에 서버의 자원을 효율적으로 공유하고 분배해서 사용할 수 있어야 한다. 또한 중요 한 기업의 핵심 정보를 처리하거나 미션 크리티컬한 금융, 원자력, 항공, 국방 등의 시 스템을 다루기도 하기 때문에 보안과 안정성, 확장성 면에서도 뛰어나야 한다. 따라서 뛰어난 성능과 서비스의 안정성이 요구되고 그런 점을 고려한 개발 기술이 필요하다.

이유 2. 핵심기능인 비즈니스 로직의 복잡함의 증가

  • 최근 모든 회사의 시스템은 어플리케이션으로 동작한다. 즉 수 많은 부서와 직무들에 적합한 어플리케이션을 개발해야 하며 지속적으로 유지보수 할 일이 증가하였다. 비즈니스 환경이 급변하고 어플리케이션 기반의 업무 프로세스가 자리잡음으로써 비즈니스 로직의 복잡성도 급격하게 증가되고 있다.

복잡함을 해결하려는 도전

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

  • 현실적으로 기술 및 비즈니스 로직의 복잡도를 개발을 편하게 하기 위해서 낮출 수 없다. 기술과 비즈니스 로직 둘을 분리함으로써 복잡도를 낮출 수 있다.

비침투적인 방식을 통한 효과적인 해결

  • 핵심 비즈니스 로직과 기술적 복잡함을 분리한다. 비즈니스 로직에 기술 로직은 포함되지 않는다. 즉 기술적인 부분과 비즈니스 로직을 분리함으로써, 개발자가 신경써야 하는 비즈니스 로직은 타 기술이 침투하지 않는다. 이를 통해 객체지향을 통한 복잡성을 감소시키는 방법을 자유롭게 적용할 수 있는 기반이 마련되었다라고 할 수 있다.

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

기술에 대한 접근 방식이 일관성이 없고 특정 환경에 종속적이다.

  • 서비스 추상화를 통한 해결 - 트랜잭션 추상화나 예외 반환 기능 등
  • 기술적인 복잡함은 일단 추상화를 통해 로우 레벨의 기술 구현 부분과 기술을 사용하는 인터페이스로 분리하고, 환경과 세부 기술에 독립적인 접근 인터페이스를 제공하는 것

기술적인 처리를 담당하는 코드가 성격이 다른 코드에 섞여 등장한다

  • 트랜잭션 보안적용 데이터와 예외의 일괄 변환 로깅과 감사 - AOP
  • 기술과 비즈니스 로직을 분리시킴으로써 복잡성을 감소시키고 중복을 제거한다.

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

스프링이 크게 관여하지 않는다. 비침투적인 기술을 통해서 스스로를 드러내지 않고 개발자는 객체지향적으로 코딩하는 것에만 전념하면 된다. 즉 기존에 자바의 장점을 살리지 못하게 했던 요소들을 제거해주는 것이다.

기술적인 복잡함을 해결하는 문제나 기술적인 복잡함이 비즈니스 로직에 침범하지 못하도록 분리하는 경우에도 DI가 바탕이 된 여러 가지 기법이 활용된다. 반면에 비즈니스 로직 자체의 복잡함을 해결하려면 DI보다는 객체지향 설계 기법이 더 중요하다.순수한 비즈니스 로직만을 담고 있는 코드에는 객 체지향 분석과 설계에서 나온 도메인 모델을 쉽게 적용할 수 있기 때문이다. 객체지향적 인 특성을 잘 살린 설계는 상속과 다형성, 위임을 포함해서 많은 객체지향 디자인 패턴과 설계 기법이 잘 녹아들어 갈 수 있다.

POJO 프로그래밍

‘분리됐지만 반드시 필요한 엔터 프라이즈 서비스 기술을 POJO 방식으로 개발된 애플리케이션 핵심 로직을 담은 코드에 제공한다’는 것이 스프링의 가장 강력한 특징과 목표

스프링의 핵심 - POJO

Plain Old Java Object - 자바 오브젝트 그 자체

출처 - 토비의 스프링

POJO의 조건

특정 규약에 종속되지 않는다.

  • 순수한 애플리케이션 로직을 담고 있는 오브젝트 코드가 특정 환경에 종속되게 만드는 경우라면 그것 역시 POJO라고 할 수 없다. POJO는 환경에 독립적이어야 한 다.특히 비즈니스 로직을 담고 있는 POJO 클래스는 웹이라는 환경정보나 웹 기술을 담고 있는 클래스나 인터페이스를 사용해서는 안 된다.
  • 애노테이션이 단지 코드로 표현하기는 적절치 않은 부가적인 정보를 담고 있고, 그 때문에 환경에 종속되지만 않는다면 여전히 POJO라고 할 수 있다. 하지만 애노테이션이나 엘리먼트 값에 특정 기술과 환경에 종속적인 정보를 담고 있다 면 그때는 POJO로서의 가치를 잃어버린다고 할 수 있다. 진정한 POJO란 객체지향적인 원리에 충실하면서, 환경과 기술에 종속되지 않고 필 요에 따라 재활용될 수 있는 방식으로 설계된 오브젝트를 말한다. 그런 POJO에 애플리케이션의 핵심 로직과 기능을 담아 설계하고 개발하는 방법을 POJO 프로그래밍이라고 한다.
  • 결국 객체지향적으로 설계되어 변경에 용이하고 유지보수하기 편리한 형태로 개발된 오브젝트이면서 특정 환경에 종속적이지 않은 오브젝트를 POJO라고 볼 수 있다.

POJO의 장점

POJO가 될 수 있는 조건 그대로 POJO의 장점이 된다.

  • 특정 기술과 환경에 종속적이지 않은 코드는 깔끔하다.
  • 자동화된 테스트에 유리하다.
  • 객체지향적인 설계를 자유롭게 적용할 수 있다.

POJO 프레임워크


출처 - 토비의 스프링

스프링은 POJO를 이용한 엔터프라이즈 애플리케이션 개발을 목적으로 하는 프레임워크라고 했다. POJO 프로그래밍이 가능하도록 기술적인 기반을 제공하는 프레임워크를 POJO 프레임워크라고 한다.

스프링은 개발자들 이 복잡한 엔터프라이즈 기술보다는 이러한 객체지향적인 설계와 개발의 원리에 좀 더 집중할 수 있도록 기회를 준다. 동시에 스프링이 제공하는 기술과, 프레임워크 API 및 확 장 포인트는 그것을 이용하는 코드가 자연스럽게 객체지향적인 설계원리를 따라가도록 이끌어주기도 한다

스프링의 기술

스프링에는 POJO 프로그래밍을 손쉽게 할 수 있도록 지원하는 세 가지 가능기술을 제공한다 스프링의 기술들은 스프링 프레임워크가 만들어진 진정한 목표인 POJO 기반의 엔 터프라이즈 개발을 편리하게 해주는 도구일 뿐이다. 또 다른 관점에서 보자면 IoC/DI, AOP, PSA라는 것 자체가 이미 스프링이 중요한 가치를 두는 객체지향의 원리를 충실히 적용해서 나온 결과이기도 하다.

IOC / DI

왜 두 개의 오브젝트를 분리해서 만들고, 인터페이스를 두 고 느슨하게 연결한 뒤, 실제 사용할 대상은 DI를 통해 외부에서 지정하는 것일까? A→B라는 의존관계를 갖는 오브젝트 구조라고 생각해보자. 여기서 확장은 B가 자유 롭게 변경될 수 있음을 의미한다. 이는 B가 변경돼도 A는 아무런 영향을 받지 않고 그대 로 유지 가능하다는 뜻이기도 하다.

DI의 활용 방법

  • 핵심기능의 변경

    DI의 가장 대표적인 적용 방법은 바로 의존 대상의 구현을 바꾸는 것이다. 예를 들어보면 서비스 오브젝트가 사용하는 DAO가 있다고 할 때, DAO의 구현을 JDBC로 했다가, 그것을 JPA, 하이버네이트, JDO, iBatis 등으로 변경하는 것을 생 각할 수 있다. 구현 방식을 통째로 바꾸는 것이다.

  • 핵심기능의 동적인 변경

    동적으로 매번 다르게 변경할 수 있다. DI도 기본적으로는 런타임 시에 동적으로 의존 오브젝트를 연결해주는 것이긴 하지만, 일단 DI 되고 나면 그 후로는 바뀌지 않는다. 즉 동적인 방식으로 연결되
    지만 한번 DI되면 바뀌지 않는 정적인 관계를 맺어주는 것이다.

    하지만 DI를 잘 활용하면 애플리케이션이 동작하는 중간에 그 의존 대상을 다이내믹하게 변경할 수 있다.

  • 부가기능의 추가

    트랜잭션 기능을 부여했던 것이 그 대표적인 예다. 때로는 핵심기능은 그대로 둔 채로 결과나 전달 파라미터를 조작할 수도 있고, 파라미터나 리턴 결과를 활용해 로깅 이나 보안 처리 같은 부가적인 작업을 수행할 수도 있다. 부가기능이라기보다는 부가 작업이라고 본다면 이벤트 발생 작업의 추가 같은 것도 생각해볼 수 있다. 부가기능의 추가 방식을 특정 오브젝트가 아니라 좀 더 많은 대상으로 일반화해서 적용하면 AOP 가 된다.

  • 인터페이스의 변경

    인터페이스가 다른 다양한 구현을 같은 방식으로 사용 하도록, 중간에 인터페이스 어댑터 역할을 해주는 레이어를 하나 추가하는 방법도 있 다. DI의 응용 방법 중 하나이자 스프링의 대표적인 기술로도 분류되는 일관성 있는 서비스 추상화PSA가 그런 방법이다. PSA는 클라이언트가 일관성 있게 사용할 수 있 는 인터페이스를 정의해주고 DI를 통해 어댑터 역할을 하는 오브젝트를 이용하게 해 준다. 이를 통해서 다른 인터페이스를 가진 로우레벨의 기술을 변경하거나 확장해가 면서사용할수있는것이다.

  • 프록시

  • 템플릿과 콜백

    템플릿/콜백 패턴은 DI의 특별한 적용 방법이다. 반복적으로 등장하지만 항상 고정적 인 작업 흐름과 그 사이에서 자주 바뀌는 부분을 분리해서 템플릿과 콜백으로 만들고 이를 DI 원리를 응용해 적용하면 지저분하게 매번 만들어야 하는 코드를 간결하게 만 들 수 있다.

  • 싱글톤과 오브젝트 스코프

    DI가 필요한 중요한 이유 중 한가지는DI 할 오브젝트의 생명주기를 제어할 수 있다 는 것이다. DI를 프레임워크로 이용한다는 건 DI 대상 오브젝트를 컨테이너가 관리한 다는 의미다. 오브젝트의 생성부터 관계설정, 이용, 소멸에 이르기까지의 모든 과정을 DI 컨테이너가 주관하기 때문에 그 오브젝트의 스코프를 자유롭게 제어할 수 있다.

  • 테스트

    마지막으로 살펴볼 DI의 중요한 용도는 바로 테스트다. 여타 오브젝트와 협력해서 동 작하는 오브젝트를 효과적으로 테스트하는 방법은 가능한 한 고립시키는 것이다. 즉 다른 오브젝트와의 사이에서 일어나는 일을 테스트를 위해 조작할 수 있도록 만든다. 그래야만 테스트 대상인 오브젝트의 기능에 충실하게 테스트가 가능하다. 자칫 다른 오브젝트와의 협력을 통해 동작하는 기능을 다 허용하고 테스트하다가는 한 번에 수 십 개의 오브젝트와 DB, 환경까지 모두 테스트해야 하는 부담을 안을 수 있다.

AOP

부 서비스는 순수한 객체지향 기법만으로는 POJO의 조건을 유지한 채로 적용하기 힘들다. 바로 이런 문제를 해결하기 위해 AOP가 필요하다. 스프링의 AOP는 스프링이 POJO 프로그래밍을 지원하려는 그 핵심 목적을 위해 중요한 역할을 하고 있다.

AOP 적용 기법

  • 스프링과 같이 다이나믹 프록시를 이용하는 방법

    부가기능을 부여할 수 있는 곳은 메소드의 호출이 일어나는 지점뿐이라는 제약이 있다. 인터페이스와 DI를 활용하는 데코레이터 패턴이 기반원리이기 때문이다. 부가기능을 구현한 코드나 기능을 적용할 대상을 찾는 방법 모두 평범한 자바 클래스로 만들면 된다. 스프링의 기본적인 AOP 구현 방법은 다이내믹 프록시를 이용하는 프록시 AOP 방식이다. 엔터프라이즈 개발에서 필요로 하는 AOP는 대부분이 이 프록시 방식의 AOP면 된다.

  • AspectJ

    AspectJ는 프록시 방식의 AOP에서는 불가능한 다양한 조인 포인트를 제공한다. 메소드 호출뿐 아니라 인스턴스 생성, 필드 액세스, 특정 호출 경 로를 가진 메소드 호출 등에도 부가기능을 제공할 수 있다

AOP 적용 단계

  1. 미리 준비된 AOP 이용

    Transaction | Configurable - AspectJ

  2. 전담팀을 통한 정책 AOP 적용

    대표적으로 비즈니스 로 직을 가진 오브젝트에 대한 보안, 특정 계층의 오브젝트 이용 전후의 작업 기록을 남 기는 로깅, 데이터 추적을 위한 트레이싱, 특정 구간의 실시간 성능 모니터링과 같은 정책적으로 적용할 만한 기능에 AOP를 이용하는 것이다.

    서비스 계층에서 던질 수 있는 예외의 종류가 정해져 있다고 해보자. 그런 데 개발자가 임의의 예외를 만들거나 선택해서 마구 사용할 수도 있다. 이런 경우라면 서비스 계층의 메소드에 대해 예외가 던져졌을 때만 동작하는 AOP 모듈을 만들 수 있다

  3. AOP의 자유로운 이용

    세부적인 AOP를 이용할 수 있다. 큰 범위에 걸쳐서 적용되는 기능은 아니지만 한 모듈 또는 특 정 기능 안에서도 AOP로 분리하면 유용한 것들이 있다.

PSA

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

스프링은 JavaEE를 기본 플랫폼으로 하는 자바 엔터 프라이즈 개발에 주로 사용된다. 따라서 다양한 JavaEE 기술에 의존적일 수밖에 없다. 특 정 환경과 기술에 종속적이지 않다는 게 그런 기술을 사용하지 않는다는 뜻은 아니다. 다 만 POJO 코드가 그런 기술에 직접 노출되어 만들어지지 않는다는 말이다.

서비스 추상화를 위해 필요한 기술은 DI뿐이다. 결국 DI 응용 방법의 한 가지이므로 DI를 적극 활용해서 개발한다면 서비스 추상화는 자연스럽게 만들어 쓸 수 있다.

정리

  • 스프링은 그 개발철학과 목표를 분명히 이해하고 사용해야 한다.

  • 스프링은 오픈소스 소프트웨어이며, 애플리케이션 개발의 모든 기술과 영역을 종합

    적으로 다루는 애플리케이션 프레임워크다.

  • 엔터프라이즈 애플리케이션 개발의 복잡함은 비즈니스 로직과 엔터프라이즈 시스템
    의 기술적인 요구에 의해 발생한다. 기존의 접근 방법은 이 복잡도를 낮추지 못하며
    자바의 객체지향적인 장점을 포기해야 한다는 문제점이 있다.

  • 자바의 근본인 객체지향적인 원리에 충실하게 개발할 수 있으며, 환경과 규약에 의존
    적이지 않은 POJO를 이용한 애플리케이션 개발은 엔터프라이즈 시스템 개발의 복잡
    함이 주는 많은 문제를 해결할 수 있다.

  • 스프링의 목적은 이런 POJO를 이용해 엔터프라이즈 애플리케이션을 쉽고 효과적으
    로 개발할 수 있도록 지원해주는 데 있다.

  • POJO 방식의 개발을 돕기 위해 스프링은 IoC/DI, AOP, PSA와 같은 가능기술을 프
    레임워크와 컨테이너라는 방식을 통해 제공한다.

0개의 댓글