본문 바로가기
챕터정리방

[9장] 스프링 프로젝트 시작하기

by gogumi 2022. 2. 9.

스프링을 이용해 애플리케이션을 처음 구성할 때 알아야 할 기본적인 내용을 살펴보자. 스프링 개발에 도움이 되는 개발 툴과 빌드 방법, 아키텍처 종류와 특징에 대해서도 알아보자.

1. 자바 엔터프라이즈 플랫폼과 스프링 애플리케이션

스프링으로 만들 수 있는 애플리케이션의 종류에는 제한이 없으나 스프링은 주로 자바 엔터프라이즈 환경에서 동작하는 애플리케이션을 개발하는 목적으로 사용된다.

클라이언트와 백엔드 시스템

엔터프라이즈 애플리케이션은 자신이 클라이언트가 돼서 또 다른 엔터프라이즈 시스템에 서비스를 요청할 수 있다. 또는 DB나 레거시 시스템 같은 엔터프라이즈 정보 시스템(EIS)이라는 백엔드 시스템의 기능을 이용해 동작하기도 한다.

가장 많이 사용되는 구조는 클라이언트가 웹 브라우저이고 백엔드 시스템이 DB인 구성이다. 스프링 엔터프라이즈 애플리케이션이 이용하는 백엔드 시스템으로는 DB, 메시징 서버, 메일 서버, 메인프레임도 가능하다. 한 번에 여러 종류의 백엔드 시스템을 이용할 수도 있다.

스프링 엔터프라이즈 애플리케이션의 서비스와 협력 구조

애플리케이션 서버

스프링으로 만든 애플리케이션을 자바 서버환경에 배포하려면 JavaEE(또는 J2EE) 서버가 필요하다. JavaEE 표준을 따르는 애플리케이션 서버는 크게 두 가지로 구분할 수 있다.

JavaEE의 대부분의 표준 기술을 지원하고 다양한 형태의 모듈로 배포가 가능한 완전한 웹 애플리케이션 서버 (WAS) 웹 모듈의 배포만 가능한 경량급 WAS 또는 서블릿/JSP 컨테이너다.

  • 경량급 WAS/서블릿 컨테이너 : 스프링은 톰캣이나 제티 같은 가벼운 서블릿 컨테이너만 있어도 충분하다. EJB나 WAS가 제공하는 분산 서비스 등이 굳이 필요하지 않다면 서블릿 컨테이너로도 엔터프라이즈 애플레케이션에 필요한 핵심기능을 이용할 수 있다.
  • WAS : 고가의 WAS를 사용하면 고도의 안정성이나 안정적인 리소스 관리 등 유리한 점이 많다. 특히 자바 엔터프라이즈 버전(JavaEE) 표준을 최대한 활용할 수 있다.

실제로 개발환경과 운영환경에서 가장 많이 사용되는 자바 서버는 웹 모듈만 지원하는 아파치 톰캣이다. 오픈소스 제품인 톰캣을 그대로 사용하기 불안하다면 tcServer가 좋은 대안이다.

스프링 애플리케이션의 배포 단위

  • 독립 웹 모듈 : 스프링은 보통 war로 패키징된 독립 웹 모듈로 배포된다.
  • 엔터프라이즈 애플리케이션 : 경우에 따라 확장자가 ear인 엔터프라이즈 애플리케이션으로 패키징해 배포할 수도 있다. 스프링 애플리케이션에서 EJB 모듈을 긴밀하게 사용하거나 EJB 모듈에서 스프링 애플리케이션을 이용해야 할 경우 등.
  • 백그라운드 서비스 모듈 : J2EE 1.4에서 등장한 rar 패키징 방법. 리소스 커넥터를 만들어 배포할 때 사용하는 방식인이다. 스프링 애플리케이션이 UI 없이 서버 내에서 백그라운드 서비스처럼 동작할 경우.

2. 개발도구와 환경

SpringIDE 플러그인

SpringIDE는 스프링 개발에 유용한 기능을 제공하는 플러그인의 모음이다. SpringIDE의 XML 에디터의 자동완성 기능에는 다음과 같은 것들이 있다.

  • 빈 클래스 이름 자동완성
  • 빈 설정 오류검증 기능
  • 프로젝트 생성, 설정파일 생성, 빈 등록 위저드
  • 빈 의존관계 그래프
  • AOP 적용 대상 표시
  • 기타 지원 기능

STS 플러그인

STS 플러그인은 스프링 개발과 편집을 지원하는 SpringIDE에 더해서 스프링 애플리케이션의 서버 배치와 같은 추가 기능을 제공한다. STS는 대부분의 최신 JavaEE 서버로의 배치는 물론이고 스프링에 최적화된 애플리케이션 서버인 tcServer, OSGi 플랫폼인 dmServer 등으로 배치할 수 있는 기능을 제공한다.

기타 플러그인

  • M2Eclipse : Maven을 지원하는 이클립스 플러그인
  • AJDT(AspectJ Development Tool) : 이클립스에서 AspectJ AOP를 이용한 개발을 지원
  • VMCI(Virtual Machine Core Integration) : VMWare 서버 또는 워크스테이션과의 연동을 지원
  • 이클립스 표준 플러그인 : WTP(Web Tool Platform), EMP(Eclipse Modeling Project), Mylyn, DSDP(Device Software Development Platform) 등

라이브러리 관리의 어려움

스프링 프로젝트에 포함될 라이브러리의 종류는 적게는 5~6개에서 많게는 수백여 개에 달할 것이다. 이중 필요한 기능과 기술에 따라 적절히 선택해야 한다. 또한 각 라이브러리마다 정확히 어떤 버전을 사용해야 할지도 알아야 한다.

복잡한 의존관계 속에서 같은 라이브러리의 다른 버전이 동시에 필요한 경우 비정상적으로 동작할 가능성이 있다. 이를 해결할 가장 간단한 방법은 재패키징(repackaging)이다. 한쪽 버전의 클래스를 다른 패키지로 옮겨 서로 구별되는 클래스로 만드는 방법이다.

이렇게 스프링 애플리케이션을 만들 때 필요한 라이브러리의 종류와 버전을 적절히 선정하고 개발하면서 추가적으로 필요한 라이브러리를 추가, 제거하는 등의 관리 작업은 쉽지 않다.

라이브러리 선정

가장 먼저 해야 할 작업은 스프링으로 만드는 애플리케이션에서 정확히 어떤 기능이 필요한지 정리하는 것이다. 이를 지원하는 기술이 여러 가지라면 그중 어떤 것을 사용할지도 정해야 한다.

스프링 모듈 : 사용할 기능, 기술 목록이 만들어졌으면 스프링 모듈부터 선정한다. 20개의 스프링 모듈 사이에는 의존관계가 있으니 이를 잘 살피어 필수 의존모듈과 선택 의존모듈을 구분해 선정하자.

라이브러리 : 스프링의 각 모듈은 경우에 따라 상용 제품의 라이브러리에 의존한다. 해당 프레임워크와 라이브러리 문서를 참조해 필요한 라이브러리가 어떤 것인지 찾아보자.

빌드 툴과 라이브러리 관리

빌드 툴이 지원하는 의존 라이브러리 관리 기능에 대해 알아보자. IDE를 사용하지 않는 경우에도 일관된 빌드가 가능하도록 만드는 것이 중요하다. 따라서 자동빌드 기능을 지원하는 IDE를 기본적으로 이용하면서 ANT나 Maven 같은 환경에 독립적인 빌드 툴을 함께 사용하는 것이 좋다.

스프링의 모든 모듈은 POM 정보를 갖고 있다. 이를 참고하면 모듈을 사용하는 데 필요한 라이브러리가 어떤 것이고 어떤 버전인지 알 수 있다. 이런 POM에 담긴 의존정보를 활용하면 라이브러리 관리가 쉬워질까?

그렇지 않다. 어떤 모듈이 제공하는 기능 중 실제 사용하는 것에 따라, 로우레벨 구현 기술을 어떤 것을 사용할지에 따라 실제 필요한 라이브러리가 달라지기 때문이다.

기업 내에서 사용하는 의존 라이브러리의 그룹을 만들고 이를 POM과 같은 빌드 툴이 활용할 정보로 생성해두면 다음부터는 편리하게 이를 조합해 모듈과 라이브러리를 지정할 수 있다.


3. 애플리케이션 아키텍처

클라이언트와 백엔드 시스템의 종류와 사용 기술, 연동 방법을 정했다면 시스템 레벨의 아키텍처는 대략 구성되었다. 다음으로는 스프링 웹 애플리케이션의 아키텍처를 결정해야 한다.

아키텍처는 어떤 경계 안의 내부 구성요소들이 어떤 책임을 갖고 있고, 어떤 방식으로 서로 관계를 맺고 동작하는지를 규정하는 것이라고 할 수 있다.

계층형 아키텍처

관심, 성격, 책임, 변하는 이유와 방식이 서로 다른 것들을 분리해 각 요소의 응집도는 높이고 서로의 결합도는 낮춰왔다.

아키텍처와 SoC

지금까지는 오브젝트 레벨에서 분리했지만 아키텍처 레벨에서 좀 더 큰 단위에 대해서도 동일하게 적용할 수 있다. 분리된 각 오브젝트는 독자적으로 개발과 테스트가 가능해서 개발과 변경 작업이 모두 빨라지고 구현 방법과 세부 로직은 서로 영향을 주지 않고 변경될 수 있을 만큼 유연해진다.

이처럼 책임과 성격이 다른 것을 그룹으로 만들어 분리하는 것을 아키텍처 차원에서는 계층형 아키텍처(layered architecture) 또는 멀티 티어 아키텍처라고 한다. 보통 웹 엔터프라이즈 애플리케이션은 세 개의 계층을 갖는다고 해서 3계층 애플리케이션이라고도 한다.

3계층 아키텍처와 수직 계층

3계층 아키텍처는 백엔드의 DB나 레거시 시스템과 연동하는 인터페이스 역할을 하는 데이터 액세스 계층, 비즈니스 로직을 담고 있는 서비스 계층, 주로 웹 기반의 UI를 만들어내고 그 흐름을 관리하는 프레젠테이션 계층으로 구분한다.

  • 데이터 엑세스 계층 : DAO계층 또는 EIS(Enterprise Information System) 계층. 장기적인 데이터 저장을 목적으로 하는 DB이용이 주된 책임이다. 데이터 엑세스 계층 안에서도 역할에 맞게 추상화 레벨에 따라 수직적으로 나눌 수 있다.
  • 서비스 계층 : 잘 만들어진 스프링 애플리케이션의 서비스 계층 클래스는 이상적인 POJO로 작성된다. 비즈니스 로직 핵심을 잠 담아내고 이를 쉽게 테스트하고 유연하게 확장할 수 있다. 서비스 계층은 DAO 계층을 호출하고 이를 활용해 만들어진다. 이상적인 서비스 계층은 DB와 연결되는 데이터 엑세스 계층이 바뀌거나 클라이언트와 연결되는 프레젠테이션 계층이 모두 바뀌어도 그대로 유지 될 수 있어야 한다.
  • 프레젠테이션 계층 : 매우 다양한 기술과 프레임워크의 조합을 가질 수 있다. 엔터프라이즈 애플리케이션의 프레젠테이션 계층은 클라이언트의 종류와 상관없이 HTTP 프로토콜을 사용하는 서블릿 기술이 바탕이 된다. 다른 계층과 달리 클라이언트까지 그 범위를 확장될 수도 있다.

애플리케이션 정보 아키텍처

애플리케이션의 주요 상태정보는 클라이언트나 백엔드 시스템에 분산돼서 보관된다. 비교적 장기간 보관되는 상태정보는 주로 DB나 메인프레임 같은 EIS백엔드 시스템에 저장된다. 하나의 업무 작업이 여러 번의 요청과 페이지에 걸쳐 일어나는 경우에 유지돼야 하는 임시 상태정보는 클라이언트에 일시적으로 보관되기도 하고 서버의 사용자별 세션 메모리에 저장되기도 한다.

애플리케이션에서 정보를 어떤식으로 다룰지를 결정하는 일도 아키텍처를 결정할 때 중요한 기준이 된다.

  1. 단순히 데이터로 다루는경우
    • 정보를 단순히 값이나 값을 담기 위한 목적의 오브젝트 형태로 취급하는 구조.
    • DB에서 가져온 정보를 값으로 취급하는 코드를 만들고 사용자 화면과 연결해준다.
    • 비즈니스 로직이 DB 내부의 저장 프로시저나 SQL에 담겨 있는 경우가 많다.
    • DB에 무게를 두는 구조와 서비스 계층의 코드에 무게를 두는 구조로 구분.
  2. 오브젝트로 다루는 경우
    • 도메인 모델을 반영하는 오브젝트 구조를 만들어주고 사용.

DB/SQL 중심의 로직 구현 방식

데이터 중심 구조의 특징은 하나의 업무 트랜잭션에 모든 계층의 코드가 종속되는 경향이 있다는 점이다. 이런 식의 개발 방법과 아키텍처는 자바 기술이 발전하기 이전의 엔터프라이즈 시스템 2계층 구조에서도 흔히 발견된다.

개발하기에는 쉽지만 자바 코드를 단지 DB와 웹 화면을 연결해주는 단순한 인터페이스 도구로 전락시킨다. 자바의 오브젝트는 단지 HTTP 서비스 채널을 만들어고 JDBC를 이용해 DB기능을 사용하게 하는 스크립트 정도로 역할이 축소된다.

또한 변화에 매우 취약하다. 객체지향의 장점을 별로 활용하지 않고 각 계층 코드가 긴밀하게 연결되어 있기 때문이다.

반면 로직을 애플리케이션으로 가져오면 비용도 절감되며 안정성도 높아지고, 코드를 검증하기도 매우 편하다. 따라서 DB에는 부하를 가능한 한 주지 않는 간단한 작업만 하고 복잡한 로직은 오브젝트에 담아 애플리케이션 내에서 처리하도록 만드는 것이 좋다.

오브젝트 중심 아키텍처

객체지향 분석과 모델링의 결과로 나오는 도메인 모델을 오브젝트 모델로 활용한다. 오브젝트 중심 아키텍처가 데이터 중심 아키텍처와 다른 가장 큰 특징은 도메인 모델을 반영하는 오브젝트 구조를 만들어두고 그것을 각 계층 사이에서 정보를 전송하는 데 사용한다는 것이다. 

데이터와 오브젝트

간단한 예를 가지고 데이터와 오브젝트 방식을 비교해 보자.

1:N관계의 카테고리와 상품이라는 두 가지 엔티티가 있다.

Category

필드명 타입 설정
CategoryId int Primary Key
Description varchar(100)  

 

Product

필드명 타입 설정
ProductId int Primary key
Name varchar(100)  
Price int  
CategoryId int Foregin Key(Category)

 

조건에 맞는 모든 카테고리와 상품 정보를 가져와서 화면에 출력하는 기능을 만든다고 해보자.

1. 데이터 중심 아키텍처 관점

  • SQL과 DB관점에서 생각한다.
  • 이 두 개의 정보를 조합해서 가져오는 방법은 JOIN을 이용해 2차원 구조의 정보를 만드는 것이다. 따라서 DAO에서 다음과 같은 SQL을 사용하게 만들 것이다.
Select c.categoryid , c.description, p.productid, p.name, p.price
from product p join category c 
on p.categoryid= c.categoryid

 

while(rs.next()){
    Map<String,Object> resMap = new HashMap<String, Object>();
    resMap.put(“categoryid”,rs.getString(1));
    resMap.put(“description“, rs.getString(2));
    ...
    list.add(resMap);
}

 

  • 서비스 계층에 전달되는 것은 List<Map<String, Object>>타입이다.
  • 이 타입만 봐서는 안에 담긴 내용이 어떤 것인지 알 수 없다. 따라서 이 결과를 사용하는 서비스 계층이나 프레젠테이션 계층의 코드에서는 DAO 메소드에서 두 개의 테이블을 조인해 다섯 가지 필드의 값을 가져오고, 필드 이름을 키로 갖는 맵에 값을 저장했음을 알아야 사용할 수 있다.
  • 만약 DAO에서 SQL을 변경하거나 필드 개수나 순서, 이름을 바꾼다면 서비스 계층과 프레젠테이션 계층의 코드도 같이 변경돼야 한다.
  • 이렇게 데이터 중심의 아키텍처에서는 DAO가 만드는 SQL의 결과에 모든 계층의 코드가 의존하게 된다.

2. 오브젝트 중심 아키텍처 관점

  • 애플리케이션에서 사용되는 정보가 도메인 모델의 구조를 반영해서 만들어진 오브젝트 안에 담긴다.
  • 도메인 모델은 애플리케이션 전 계층에서 동일한 의미를 가진다.
  • 따라서 도메인 모델이 반영된 도메인 오브젝트도 전계층에서 일관된 구조를 유지한 채로 사용될 수 있다.
  • SQL이나 웹페이지의 출력 포맷, 입력폼 등에 종속되지 않는 일관된 형식의 애플리케이션의 정보를 다룰수 있다.

도메인 오브젝트

public class Category{
    int categoryid;
    String description;
    Set<Product> products; //0~N개의 Product를 참조하고 있는 컬렉션을 가질 수 있다.
    //접근자, 수정자
    ...
}


public class Product{
    int productid;
    Stringname;
    int price;
    Category category;  //1개의Category를 가리키는 레퍼런스를 직접 갖고 있다.
    //접근자, 수정자
    ...
}
//자바의 레퍼런스 개념은 상호 참조가 가능하게 만들 수 있다.

 

  • 애플리케이션 어디에서도 사용될 수 있는 일관된 형식의 도메인 정보를 담고 있다.
  • Product 클래스에는 Product 테이블처럼 categoryid라는 외래키가 없다. 대신 Category 오브젝트를 가리키는 레퍼런스 변수를 갖고 있다. 반대로 하나의 Category는 여러개의 Product와 관계를 가질 수 있으므로 Set이라는 컬렉션을 이용해 여러 개의 Product 오브젝트를 참조하게 만들 수 있다.

데이터 중심 방식에서는 Category와 그에 대응되는 Product를 찾아 SQL을 이용해 조인한 다음 하나의 맵에 뭉뚱그려서 가져왔다. 반면에 오브젝트 중심 방식에서는 테이블의 정보과 그 관계를 유지한 채로 정확한 개수의 Category 오브젝트와 그에 대응되는 Product 오브젝트로 만들어 사용한다.

도메인 오브젝트 사용의 문제점

  • 장점
    1. 이해하기 쉽고 로직 작성도 수월하다.
    2. 프레젠테이션 영역에서도 정의된 도메인 오브젝트 구조만 알고 있다면 DAO가 작성되지 않았어도 뷰를 미리 만들 수 있다.
  • 단점
    1. 최적화된 SQL에 비해 성능면에서 조금 손해를 감수해야 할 수도 있다.
    2. DAO는 비즈니스 로직의 사용 방식을 알지 못하므로, 모든 필드 값을 다 채워서 전달한다.
    3. Product 정보만 필요한데 Category 정보도 오브젝트로 만들어 가져오는 것은 상당한 낭비이다.

이런 문제를 해결하는 접근 방법을 알아보자.

  1. 지연된 로딩(lazy loading) 기법 : 일단 최소한의 오브젝트 정보만 읽어두고 관계하고 있는 오브젝트가 필요한 경우에만 다이내믹하게 DB에서 다시 읽어온다.
  2. RDB 매핑(ORM) 기술 사용 방
    • JPA, JDO, 하이버네이트, TopLinK 등의 기술을 사용한다.
    • 지연 로딩 기법을 제공해주기 때문에 직접 만들지 않아도 된다.
    • 복잡한 DAO 코드를 만들지 않아도 된다.
    • 자주 변경되지 않으면서 많은 로직에서 참조되는 레퍼런스 테이블을 캐시에 담아 사용할 수 있다.

오브젝트 중심 아키텍처는 오브젝트의 활용 방법을 기준으로 다시 구분할 수 있다.

빈약한 도메인 오브젝트 방식 (Anemic Domain Object)

도메인 오브젝트에 정보만 담겨 있고 정보를 활용하는 아무런 기능도 갖고 있지 않는 오브젝트이다. 비즈니스 로직을 서비스 계층에 두기 때문에 거대한 서비스 계층 구조와 비슷하다. 따라서 로지그이 재사용성이 떨어지고 중복의 문제가 발생기 쉽지만, 비즈니스 로직이 복잡하지 않다면 가장 만들기 쉽고 3계층 구조의 특징을 잘 살려서 개발할 수 있는 유용한 아키텍처다.

풍성한 도메인 오브젝트 방식 (Rich Domain Object, Smart Domain Object)

빈약한 도메인 오브젝트의 단점을 극복하고 도메인 오브젝트의 객체지향적인 특징을 잘 사용할 수 있도록 개선한 것이다. 특정 도메인 오브젝트와 깊은 관계를 가진 비즈니스 로직을 서비스 계층이 아니라 도메인 오브젝트에 넣어주어 서비스 계층의 비즈니스 로직에서 재사용하게 만든다.

응집도가 높고 간결하며, 코드 중복이 발생하지 않고 객체 지향적이다.

도메인 오브젝트는 스프링 컨테이너가 관리하는 오브젝트, 즉 빈이 아니기 때문에 DAO 오브젝트를 DI 받을 수 없다. 따라서 DAO와 기반계층 오브젝트를 DI 받아 사용할 수 있는 서비스 계층의 코드는 필요하다.

도메인 계층 방식

도메인 오브젝트에 담을 수 있는 비즈니스 로직으로 변경된 정보가 다시 DB 등에 반영되려면 서비스 계층 오브젝트의 부가적인 작업이 필요하다. 도메인 오브젝트가 요구 사항을 직접 DAO에게 요청하도록 도메인 계층의 역할과 비중을 극대화하기 위해 등장한 방식이다. 도메인 오브젝트가 기존 3계층과 같은 레벨로 격상되어 하나의 계층을 이뤄 서비스 계층과 데이터 액세스 계층 사이에 존재하게 한다.

기존 방식과는 다른 두 가지 특징이 있다.

  1. 도메인에 종속적인 비즈니스 로직의 처리는 서비스 계층이 아니라 도메인 계층의 오브젝트 안에서 진행된다.
  2. 도메인 오브젝트가 기존 데이터 액세스 계층이나 기반 계층의 기능을 직접 활용할 수 있다.

도메인 오브젝트는 다른 빈을 DI 받을 수 없다고 했는데, 도메인 계층의 도메인 오브젝트들은 어떻게 다른 빈을 이용할 수 있을까?

스프링이 관리하지 않는 도메인 오브젝트에 DI를 적용하기 위해서는 AOP가 필요하다. 스프링 AOP대신 AspectJ AOP를 사용하면 클래스의 생성자가 호출되면서 오브젝트가 만들어지는 시점을 조인 포인트로 사용할 수 있고 스프링 빈이 아닌 일반 오브젝트에도 AOP 부가기능을 적용할 수 있다.

이 방식은 이전의 어떤 방식보다 도메인 오브젝트에 많은 비즈니스 로직을 담아낼 수 있다. 그럼에도 서비스 계층의 역할이 완전히 사라지는 건 아니다. 때로는 여러 도메인 오브젝트 기능을 조합해 복잡한 작업을 진행해야 하는 경우가 있기 때문이다.

도메인 오브젝트를 독립적인 계층으로 만들려고 할 때 고려해야 할 중요한 사항이 있다. 도메인 오브젝트가 도메인 계층을 벗어나서도 사용되게 할지 결정해야 함. 선택할 수 있는 방법은 두 가지다.

  1. 여전히 모든 계층에서 도메인 오브젝트를 사용한다.
    • 주의하지 않으면 막강한 기능을 가진 도메인 오브젝트를 프레젠테이션 계층이나 뷰 등에서 사용하게 해주면 이를 함부로 사용할 위험이  있다.
    • 철저한 가이드라인을 만들어두고 이를 강력하게 적용해야 한다.
  2. 도메인 오브젝트는 도메인 계층을 벗어나지 못하게 한다.
    • 도메인 계층 밖으로 전달될 때는 별도로 준비된 정보 전달용 오브젝트에 도메인 오브젝트의 내용을 복사해서 넘겨줘야 한다. 이런 오브젝트를 DTO(Data Transfer Object)라고한다.
    • DTO는 상태 변화를 허용하지 않고 읽기전용으로 만들어지기도 한다.
    • DTO는 기능을 갖지 않으므로 사용하기 안전하고 도메인 오브젝트를 외부 계층으로부터 보호해준다.

스프링 애플리케이션을 위한 아키텍처 설계

지금까지 3단계로 역할을 분리하는 계층형 아키텍처와 정보를 다루는 방법에 따른 아키텍처의 종류를 알아봤다. 이제 각 계층에 사용될 구체적 기술 종류와 수직 추상화 계층의 도입, 세세한 기술적 조건을 결정하는 일이 남았다.

계층형 아키텍처

3계층 구조는 스프링 엔터프라이즈 애플리케이션에서 가장 많이 사용되는 구조인데, 이 3계층이라는 것은 논리적인 구분이지 꼭 오브젝트 단위로 딱 끊어져 만들어지는게 아니다. 때로는 하나의 계층이 다시 수평으로 세분화될 수도 있고 두 계층이 통합돼 하나의 오브젝트에 담길 수도 있다.

프레젠테이션 계층은 보통 MVC 패턴 또는 아키텍처를 주로 사용한다. 스프링은 이 MVC 중 컨트롤러 부분을 다시 세분화하여 여러 단계의 오브젝트로 만들 수 있도록 설계되어 있다. 이런 식으로 계층 내 역할을 세분화하는 경우도 있다.

상태 관리와 빈 스코프

아키텍처 설계에서 한 가지 더 신경 써야 할 사항은 상태 관리다. 크게는 사용자 로그인 세션 관리부터, 작게는 하나의 단위 작업이지만 여러 페이지에 걸쳐 진행되는 위저드 기능까지 애플리케이션은 하나의 HTTP 요청의 범위를 넘어서 유지해야 하는 상태정보가 있다.

서버 기반의 애플리케이션은 동시에 많은 사용자의 요청을 처리하기 위해 매번 간단한 요청을 받아 결과를 돌려주는 방식으로 동작하기 때문에 지속적으로 유지되는 상태를 갖지 않는다(stateless).

하지만 애플리케이션의 상태와 장시간 진행되는 작업정보는 유지돼야 하기 때문에, 웹 클라이언트에 URL, 파라미터, 폼 히든 필드, 쿠키 등을 이용해 상태정보 또는 서버에 저장된 상태정보에 키 값 등을 전달해야 한다.

이렇게 상태를 저장, 유지하는데 어떤 방식을 사용할지 결정하는 일은 매우 중요하다. 스프링은 기본적으로 상태가 유지되지 않는 빈과 오브젝트를 사용하는 것을 권장한다. 반면에 웹 클라이언트에 폼 정보를 출력하고 이를 수정하는 등의 작업을 위해서는 HTTP 세션을 적극 활용하기도 한다.

서드파티 프레임워크, 라이브러리 적용

스프링은 표준 기술 외에도 많이 사용되는 오픈소스 프레임워크, 라이브러리나 상용 제품과 함께 사용될 수 있다.  이런 기술을 사용할 때는 먼저 스프링이 공식적으로 지원하는 기술인지 확인해본다.

스프링이 지원하는 기술이란 무슨 의미일까?

  1. 해당 기술을 스프링의 DI 패턴을 따라 사용할 수 있다.
  2. 스프링의 서비스 추상화가 적용됐다.
  3. 스프링이 지지하는 프로그래밍 모델을 적용했다.
  4. 템플릿/콜백이 지원된다.

스프링이 어떤 기술을 지원한다는 것은 스프링이 지지하는 개발철학과 프로그래밍 모델을 따르며 해당 기술을 사용할 수 있다는 의미다.

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

[8장] 스프링이란 무엇인가?  (0) 2022.01.25
[7장] 스프링 핵심 기술의 응용  (0) 2022.01.16
[6장] AOP  (0) 2022.01.03
[5장] 서비스 추상화  (0) 2021.12.29
[5장] 서비스 추상화  (0) 2021.12.26

댓글