본문 바로가기
챕터정리방

[8장] 스프링이란 무엇인가?

by 공부중중 2022. 1. 25.

스프링의 정의

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

  • 애플리케이션 프레임워크
    • 특정 계층이나, 기술, 업무 분야에 국한되지 않고 애플리케이션의 전 영역을 포괄하는 범용적인 프레임워크이다.
  • 경량급
    • 스프링은 무거운 자바 서버(WAS)가 아닌, 가장 단순한 서버환경인 톰캣(Tomcaat)이나 제티(Jety)에서 완벽하게 동작한다.
    • 코드를 훨씬 빠르고 간편하게 작성하게 해줌으로써 생산성과 품질 면에서 유리하다는 것이 경량급이라는 말로 표현되는 스프링의 특징이다.
  • 자바 엔터프라이즈 개발을 편하게
    • 개발자가 복잡하고 실수하기 쉬운 로우레벨 기술에 많은 신경을 쓰지 않으면서도 애플리케이션의 핵심인 사용자의 요구사항, 즉 비즈니스 로직을 빠르고 효과적으로 구현하는 것을 말한다.
  • 오픈소스
    • 소스가 모두에게 공개되고, 특별한 라이선스를 취득할 필요없이 얼마든지 가져다 자유롭게 이용해도 된다는 뜻이다.
    • 오픈소스의 장점은 매우 빠르고 유연한 개발이 가능하다는 점이다.
    • 오픈소스의 단점은 지속적이고 안정적인 개발이 계속될지가 불확실하다는 점이다.

 

굳이 스프링을 사용해서 엔터프라이즈 애플리케이션 개발을 편하게 하려는 이유는 엔터프라이즈 개발이란 편하지 않기 때문이다.

 

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

복잡함의 근본적인 이유
  • 기술적인 제약조건과 요구사항이 늘어나기 때문이다.
    • 엔터프라이즈 시스템이랑 서버에서 동작하며 기업과 조직의 업무를 처리해주는 시스템을 말한다.
    • 뛰어난 성능과 서비스의 안정성이 요구되므로 기술적으로 고려할 사항이 많다. 따라서 중요해질수록 점점 더 기술적인 요구는 심화되고 그에 따른 복잡도는 증가한다.
  • 엔터프라이즈 애플리케이션이 구현해야 할 핵심기능인 비즈니스 로직의 복잡함이 증가하기 때문이다.
    • 기능 요구사항과 업무 정책 등이 바뀌기 때문에 애플리케이션을 자주 수정해야될 때, 시스템 개발과 유지보수, 추가 개발 등의 작업에 대한 부담은 커지고 그에 따른 개발의 난이도는 더욱 증가한다
복잡함을 가중시키는 원인
  • 근본적인 비즈니스 로직과 엔터프라이즈 기술이라는 두 가지 복잡함이 한데 얽혀있기 때문이다.
제거될 수 없는 근본적인 복잡함
  • 근본적으로 엔터프라이즈 개발에 나타나는 복잡함의 원인은 제거 대상이 아니고 그 복잡함을 효과적으로 상대할 수 있는 전략과 기법이 필요하다.
실패한 해결책: EJB
  • EJB의 기본 전략도 위의 두가지 종류의 복잡함을 분리하는 것지만 실패했다.
  • 기술적인 복잡함을 애플리케이션의 핵심 로직에서 일부분 분리하는데 성공했지만, 오히려 EJB라는 환경과 스펙에 종속되는 코드로 만들어져야 하는 더 큰 부담을 안게 됐기때문이다.
비침투적인 방식을 통한 효과적인 해결책: 스프링
  • EJB처럼 어떤 기술을 적용했을 때 그 기술과 관련된 코드나 규악 등이 코드에 등장하는 경우를 침투적인 기술이라고 한다. 
  • 반면 비침투적인 기술은 기술의 적용 사실이 코드에 직접 반영되지 않는다는 특징이 있다. 이것이 스프링의 성공 비결이다.

 

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

기술적 복잡함을 상대하는 전략
  • 기술에 대한 접근 방식이 일관성이 없고, 특정 환경에 종속적이다.
    • 일관성 없는 기술과 서버환경의 변화에 대한 스프링의 공략 방법은 서비스 추상화이다.
    • 기술적인 복잡함은 일단 추상화를 통해 로우레벨의 기술 구현 부분과 기술을 사용하는 인터페이스를 분리하고, 환경과 세부 기술에 독립적인 접근 인터페이스를 제공했다.
    • 스프링이 제공하는 템플릿/콜백 패턴은 기술을 사용하는 코드도 최적화된 핵심 로직에만 집중하도록 도와준다.
  • 기술적인 처리를 담당하는 코드가 성격이 다른 코드에 섞여서 등장한다.
    • 스프링의 AOP는 애플리케이션 로직을 담당하는 코드에 남아 있는 기술 관련 코드를 깔끔하게 분리해서 별도의 모듈로 관리하게 해주는 강력한 기술이다.
비즈니스와 애플리케이션 로직의 복잡함을 상대하는 전략
  • 예전에는 비즈니스 로직의 상당 부분을 DB에 두었다. 하지만 이 방법은 DB에 커다란 부담을 주는 것도 문젝, 데이터 액세스를 중심으로 로직을 다루면 개발과 유지보수는 물론이고 테스트도 매우 어렵다.
  • 따라서 엔터프라이즈 시스템 개발의 흐름은 점차로 비즈니스 로직은 애플리케이션 안에서 처리하도록 만드는 추세이다.
핵심 도구 : 객체지향과 DI
  • 기술과 비즈니스 로직의 복잡함을 해결하는 데 스프링이 공통적으로 사용하는 도구는 객체지향이다.
  • EJB는 객체지향의 장점을 취하지 못했으므로, 스프링은 자바의 기본인 객체지향에 충실한 설계가 가능하도록 단순한 오브젝트로 개발하였다.

 

POJO 프로그래밍

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

 

스프링의 핵심: POJO
  • 스프링 애플리케이션은 POJO를 이용해서 만든 애플리케이션 코드와, POJO가 어떻게 관계를 맺고 동작하는지를 정의해놓은 설계정보로 구분된다.
  • 스프링의 주요 기술인 IoC/DI, AOP와 PSA는 애플리케이션을 POJO로 개발할 수 있게 해주는 가능기술이라고 불린다.
POJO의 조건
  • 특정 규약에 종속되지 않는다.
    • POJO는 자바 언어와 꼭 필요한 API 외에는 종속되지 않아야 한다.
  • 특정 환경에 종속되지 않는다.
    • 순수한 애플리케이션 로직을 담고 있는 오브젝트 코드가 특정 환경에 종속되게 만들면 안된다.
    • 비즈니스 로직을 담고 있는 POJO 클래스는 웹이라는 환경정보나 웹 기술을 담고 있는 클래스나 인터페이스를 사용해서는 안 된다.
진정한 POJO란 객체지향적인 원리에 충실하면서, 환경과 기술에 종속되지 않고 필요에 따라 재활용될 수 있는 방식으로 설계된 오브젝트를 말한다. 그런 POJO에 애플리케잉션의 핵심 로직과 기능을 담아 설계하고 개발하는 방법을 POJO 프로그래밍이라고 할 수 있다.

 

POJO의 장점

  • POJO로 개발된 코드는 자동화된 테스트에 매우 유리하다.
  • 객체지향적인 설계를 자유롭게 적용할 수 있다.
POJO 프레임워크
  • POJO 프로그래밍이 가능하도록 기술적인 기반을 제공하는 프레임워크를 POJO 프레임워크라고 한다.
  • POJO 프레임워크로서 스프링은 자신을 직접 노출하지 않으면서 애플리케이션 POJO로 쉽게 개발할 수 있게 지원해준다.

 

스프링의 기술

스프링은 POJO 프로그래밍을 손쉽헤 할 수 있도록 세 가지 기능기술을 제공한다.

  • IoC/DI
  • AOP
  • PSA

이는 스프링이 중요한 가치를 두는 객체지향의 원리를 충실히 적용한 결과이다.

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

'유연한 확장이 가능하게 하기 위해서' 사용한다. DI는 OCP로 잘 설명될 수 있으며 유연한 확장이라는 장점은 OCP의 '확장에는 열려 있다(개방)'에 해당한다. 또한 OCP의 '변경에는 닫혀있다(폐쇄)'라는 말로도 설명할 수 있다.

DI의 활용 방법

핵심 기능의 변경

  • DI의 대표적인 적용 방법은 의존 대상의 구현을 바꾸는 것이다.
  • ex) DAO의 구현을 JDBC에서 JPA, 하이버네이트, JDO, iBatis 등으로 변경

핵심기능의 동적인 변경

  • 위와 비슷하게 핵심 기능 자체를 바꾸지만, 일반적인 DI를 이용하는 방법과 달리 동적으로 매번 다르게 변경한다.
  • 애플리케이션 동작 중간에 의존 대상을 다이내믹하게 변경할 수 있다.
  • 기술적으로 보자면 다이내믹 라우팅 프록시나 프록시 오브젝트 기법을 활용한 것이다.

부가기능의 추가

  • 핵심기능은 그대로 두고 부가기능을 추가하는 것이다.
  • ex) 데코레이터 패턴, 트랜잭션 적용

인터페이스의 변경

  • 사용하려는 오브젝트가 가진 인터페이스가 클라이언트와 호환되지 않을 때 유용하다.
  • 어댑터처럼 인터페이스가 다른 오브젝트를 클라이언트가 사용하는 인터페이스로 바꿔준다.

프록시

  • 필요한 시점에서 사용할 오브젝트를 초기화하고 리소스를 준비하게 해주는 지연된 로딩(lazy loading)이나 원격 오브젝트를 호출할 때 로컬에서 존재하는 오브젝트처럼 사용하도록 해주는 원격 프록시를 적용할 때도 프록시가 필요하다.

템플릿과 콜백

  • 반복적으로 등장하지만 고정적인 작업 흐름과 자주 바뀌는 부분을 분리해 코드를 간결하게 한다.

싱글톤과 오브젝트 스코프

  • 오브젝트 생성부터 소멸까지 모든 과정을 DI 컨테이너가 주관하기 때문에 그 오브젝트의 생명주기를 제어할 수 있다.

테스트

  • 다른 오브젝트와 협력해 동작하는 오브젝트를 테스트하기 위해서는 그 사이에서 일어나는 일을 조작할 수 있어야 한다.
  • 테스트 대상의 의존 오브젝트를 목 오브젝트로 대체하면 유용하다. DI를 위해 만든 수정자 메소드를 사용하면 테스트 코드 안에서 수동으로 목 오브젝트를 주입할 수 있다.

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

AOP는 객체지향 기술의 한계와 단점을 극복하도록 도와주는 보조적인 프로그래밍 기술이다. AOP를 사용하면 OOP를 더욱 OOP 답게 만들 수 있다. 스프링의 AOP는 스프링이 POJO 프로그래밍을 지원하려는 그 핵심 목적을 위해 중요한 역할을 한다.

AOP의 적용 기법

스프링과 같이 다이내믹 프록시를 사용하는 방법 : 기존 코드에 영향을 주지 않고 부가기능을 적용하게 해주는 데코레이터 패턴을 응용한 것이다. 부가기능을 부여할 수 있는 곳은 메소드 호출이 일어나는 지점 뿐이다. 스프링의 기본적인 AOP 구현 방법은 다이내믹 프록시를 이용하는 프록시 AOP 방식이다.

자바 언어의 한계를 넘어서는 언어의 확장을 이용하는 방법 : AspectJ라는 강력한 고급 기능을 가진 AOP를 제공하는 오픈소스 AOP 툴을 이용한다. 위 방법에서는 불가능한 다양한 조인 포인트를 제공한다.

AOP의 적용 단계

1. 미리 준비된 AOP 이용 : 처음에는 스프링이 미리 만들어 제공하는 AOP 기능을 그대로 가져다 적용한다. 대표적으로 트랜잭션이 있다. DB를 사용한다면 트랜잭션이 필요할 테니 이 트랜잭션 적용을 스프링 AOP 도입의 첫 번재 단계로 이용한다. 트랜잭션 외에도 @Configurable 애노테이션을 이용해 도메인 오브젝트에 DI를 자동적용해주는 AOP 기능이 있다.

2. 전담팀을 통한 정책 AOP 적용 : 애플리케이션 전체적으로 이용 가능한 것을 소수의 AOP 담당자 관리하에 적용할 수 있다. 보안, 로깅, 트레이싱, 실시간 성능 모니터링 등과 같은 정책적으로 적용할 만한 기능에 AOP를 이용하는 것이다. 개발자가 직접 자신의 코드에 추가하려면 큰 부담을 지게 되지만 AOP를 이용해 한 번에 적용한다면 일반 개발자의 작업에는 전혀 영향을 주지 않는다.

3. AOP의 자유로운 이용 : 이전 단계에서는 애플리케이션 전체적으로 적용되는 정책 AOP를 위주로 했다면 이제 개발자가 구현하는 기능에 적용하면 유용한 세부적인 AOP를 이용할 수 있다.

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

PSA는 환경과 세부 기술의 변화에 관계없이 일관된 방식으로 기술에 접근할 수 있게 해준다. POJO로 개발된 코드는 특정 환경이나 구현 방식에 종속적이지 않아야 한다. 이를 위해 스프링은 일관성 있는 서비스 추상화 기술을 제공한다.

서비스 추상화를 위해 필요한 기술은 DI 뿐이다. 따라서 DI를 적극 활용해 개발하면 서비스 추상화는 자연스레 만들어 쓸 수 있다.

 

 

 

 

 

'챕터정리방' 카테고리의 다른 글

[9장] 스프링 프로젝트 시작하기  (0) 2022.02.09
[7장] 스프링 핵심 기술의 응용  (0) 2022.01.16
[6장] AOP  (0) 2022.01.03
[5장] 서비스 추상화  (0) 2021.12.29
[5장] 서비스 추상화  (0) 2021.12.26

댓글