스프링 프로젝트 시작하기 (토비의 스프링 vol.1 9장)
- 스프링으로 만들 수 있는 애플리케이션의 종류에는 제한이 없다
- 자바 언어를 사용한 모든 프로젝트에 적용 가능하다
- 그렇지만 기본적으로 자바 엔터프라이즈 환경에서 동작하는 애플리케이션을 개발하는 것을 목적으로 사용된다
- 그 외의 애플리케이션 개발을 위해선 추가적인 기술이 필요
엔터프라이즈 애플리케이션이 클라이언트가 되어 다른 엔터프라이즈 시스템에 서비스를 요청할 수 있다

- JavaEE 표준을 따르는 애플리케이션 서버는 크게 두 가지로 나뉜다
- 대부분의 기술을 지원하고 다양한 형태로 배포 가능한 WAS
- 비싸다
- 여러 서버를 동시 운영할 때 유리하다
- JavaEE 표준을 최대한 활용할 수 있다
- 웹 모듈의 배포만 가능한 경량급 WAS 또는 서블릿/JSP 컨테이너
- 가벼운 서블릿 컨테이너만 있으면 된다
- 추가적인 라이브러리의 도움을 통해 기술 확장 가능
- 대부분의 기술을 지원하고 다양한 형태로 배포 가능한 WAS
- 스프링 애플리케이션의 배포 단위
- 독립 웹 모듈
- war 패키징
- 서블릿 컨테이너를 썼을 시 주가 되는 배포 방법
- 엔터프라이즈 애플리케이션
- ear 패키징
- 애플리케이션에서 EJB 모듈과의 관계가 긴밀할수록 엔터프라이즈 애플리케이션으로 통합해야 한다
- 백그라운드 서비스 모듈
- rar 패키징
- UI가 필요 없는 백그라운드 서비스로 동작할 때
- 독립 웹 모듈
- 스프링의 대포적인 IDE
- Eclipse
- IntelliJ IDEA
- NetBeans
스프링 프로젝트에는 필요한 라이브러리의 수가 많고, 버전 관리가 복잡하다
- 다양한 의존 라이브러리와 그 버전간의 충돌 문제 발생 가능성
- 같은 라이브러리의 다른 버전이 공존할 때 동일 패키지 이름의 클래스를 선택적으로 사용할 수 없다
- 해결법
- 재패키징 : 의존 라이브러리의 버전 충돌 문제를 해결하기 위해 라이브러리 클래스를 다른 패키지로 이동하여 충돌을 피하는 방법
- ex ) ASM 라이브러리 재패키징
- 라이브러리 관리 도구 : 복잡한 라이브러리 의존성을 관리하기 위한 도구
- ex ) jarjar를 이용한 재패키징 도구
- 재패키징 : 의존 라이브러리의 버전 충돌 문제를 해결하기 위해 라이브러리 클래스를 다른 패키지로 이동하여 충돌을 피하는 방법
아키텍처
시스템 내부 구성 요소들이 어떤 책임을 가지고 어떻게 상호작용하는지 규정하는 것
- 아키텍처의 핵심은 관심사 분리(Separation of Concerns, SoC) 원칙을 통해 각 요소들의 응집도를 높이고 결합도를 낮추는 것
-
오브젝트 레벨에서뿐만 아니라, 계층형 아키텍처와 같은 시스템 레벨에서도 동일하게 적용된다
- 계층형 아키텍처
- 애플리케이션의 요소들을 성격과 책임에 따라 분리된 계층으로 나눈다
- 계층 별로 독립적인 개발, 테스트 및 수정이 용이하여 유연한 확장이 가능
- 웹 기반의 엔터프라이즈 애플리케이션은 일반적으로 세 개의 계층을 갖는다고 하여 3계층(3-tier or 3-layer) 애플리케이션 이라고도 한다
- 3계층 아키텍처

- 데이터 액세스 계층
- 주로 DB와 같은 백엔드 시스템과 연동하여 데이터를 처리하는 계층
- DAO 패턴이 사용되며, 다양한 시스템과 연동할 수 있는 EIS(Enterprise Information System) 계층이라고도 불린다
- 기술적 변화에 유연하게 대처하기 위해 추상화된 계층 구조를 따르며, 필요에 따라 새로운 추상 계층을 추가할 수 있다
- 서비스 계층
- 비즈니스 로직을 담고 있는 핵심 계층
- DAO 계층을 호출하여 데이터 처리 로직을 수행하며, POJO로 설계되어야 한다
- 비즈니스 로직과 기반 서비스(메일, 메시징, 원격 호출 등)를 분리하여 독립적으로 유지할 수 있어야 한다
- 추상화 수직 계층 구조는 필요하지 않으며, 특정 기술에 종속되지 않도록 설계하는 것이 중요
- 프레젠테이션 계층
- UI를 담당하며, 웹 기반의 기술을 사용하여 사용자와 상호작용하는 계층
- 서블릿 기술을 바탕으로 다양한 클라이언트(브라우저, 플러그인, 독립형 애플리케이션 등)와 HTTP 프로토콜을 통해 연결
- 프레젠테이션 로직이 점점 클라이언트 측으로 이동하면서, RIA(Rich Internet Application)나 SOFEA(Service Oriented Front End Architecture)와 같은 기술들이 사용
- 스프링은 다양한 웹 기술과의 통합을 지원하며, 유연하게 프레젠테이션 계층을 설계할 수 있도록 돕는다
계층형 아키텍처의 설계 원칙
- 응집도와 결합도
- 각 계층은 자신의 책임에 충실해야 하며, 다른 계층과의 결합도를 낮춰야 한다
- 데이터 액세스 계층은 데이터 액세스와 관련된 모든 것을 처리하고, 비즈니스 로직이나 프레젠테이션 관련 코드를 포함하지 않아야 한다
- 계층 간 역할 분리
- 계층 간에 사용하는 인터페이스 메소드에는 특정 계층의 기술이 노출되지 않도록 해야 한다
- 예를 들어, 서비스 계층이 DAO를 호출할 때, JDBC의 ResultSet이나 SQLException 같은 기술 종속적인 예외와 오브젝트를 노출하지 않도록 주의해야 한다
- 낮은 결합도의 중요성
- 계층 간에 강한 결합이 발생하면 유연성이 떨어지고, 변경 시 다른 계층의 코드도 수정해야 하는 문제가 발생한다
- 따라서 각 계층은 독립적으로 변경 가능하도록 설계해야 한다
- 구체적인 구현의 노출 방지
- 프레젠테이션 계층의 오브젝트를 서비스 계층에 전달하는 것은 지양해야 한다
- 서비스 계층에서 웹 관련 기술이 노출되면 테스트가 어려워지고, 재사용성이 떨어진다
- 인터페이스 사용
- 계층 간 호출은 반드시 인터페이스를 통해 이뤄져야 하며, 필요한 메소드만 노출하도록 신중하게 인터페이스를 설계해야 한다
- 단순히 자바의 interface 키워드뿐만 아니라, 계층 간의 경계를 명확히 하기 위한 추상화가 필요하다
- DI와 계층 간 관계
- 스프링의 DI는 기본적으로 오브젝트 간의 관계를 다루지만, 계층 간 경계를 명확히 하도록 해야 한다
- 각 계층의 빈 오브젝트는 그 계층 내부에서만 사용되도록 주의해야 하며, 중간 계층을 건너뛰어 다른 계층의 빈을 직접 DI하지 않도록 해야 한다
- 데이터 중심 아키텍처
- 애플리케이션에 흐르는 정보를 단순한 값이나 결과 저장을 위한 오브젝트 형태로 다룬다
- 주로 DB에서 정보를 가져와 비즈니스 로직을 저장 프로시저나 SQL에 담고, 그 결과를 그대로 프레젠테이션 계층에 전달
- 이 방식에서는 각 계층이 하나의 업무 트랜잭션 단위로 강하게 결합되어, SQL의 변화가 있으면 모든 계층의 코드가 함께 변경되어야 한다
- 코드의 중복이 발생하기 쉽고, 객체지향의 장점을 살리기 어렵다. 또한, 복잡한 SQL 로직이 DB에 많이 담겨 있어 확장성과 유지보수성이 떨어진다
- 오브젝트 중싱 아키텍처
- 도메인 모델을 반영한 오브젝트 구조를 만들어 각 계층 간의 정보를 주고받는다
- 도메인 모델을 기반으로 애플리케이션 전체에서 일관된 형식의 도메인 오브젝트를 사용하며, 비즈니스 로직을 DB가 아닌 애플리케이션 서버의 오브젝트에 담아 처리
- 이 방식은 객체지향의 장점을 최대한 활용하며, 코드의 재사용성과 유지보수성이 높아진다
- 각 계층은 도메인 오브젝트를 통해 정보를 주고받으며, 특정 SQL이나 DB 구조에 종속되지 않고 독립적으로 동작할 수 있어 유연한 확장과 변경이 가능
- 도메인 오브젝트 장점
- 단순하고 명확한 비즈니스 로직 : 비즈니스 로직을 이해하기 쉽게 작성할 수 있다. 예를 들어, 특정 카테고리에 포함된 모든 상품의 가격을 계산하는 메소드를 서비스 계층에 추가할 수 있다
- 재사용성과 테스트 용이성 : 동일한 비즈니스 로직을 여러 곳에서 재사용할 수 있다. 또한 테스트 코드 작성이 쉽고, 로직이 변경될 때 코드 수정을 간편하게 할 수 있다
- 도메인 오브젝트 사용의 문제점
- 성능 저하 : 모든 필드 값을 포함한 오브젝트를 DAO에서 전달받아야 하기 때문에, 실제 필요한 필드만 사용하더라도 불필요한 데이터가 포함될 수 있어 성능에 영향을 미칠 수 있다
- 오브젝트 관계의 비효율성 : 필요한 정보 외에 관련된 오브젝트까지 함께 조회해야 하는 경우, 불필요한 데이터 로딩이 발생할 수 있다
- 해결법
- 지연된 로딩(Lazy Loading) : 필요할 때만 데이터를 가져오도록 하여 성능을 최적화할 수 있다
- JPA, Hibernate 등의 ORM 기술을 통해 도메인 오브젝트의 생성 및 데이터 액세스 최적화를 자동으로 처리할 수 있다
빈약한 도메인 오브젝트 방식
- 특징 : 도메인 오브젝트에 정보만 담겨 있고, 비즈니스 로직은 서비스 계층에 존재한다. 따라서 도메인 오브젝트는 단순한 데이터 저장소 역할만 한다
- 한계 : 비즈니스 로직의 재사용성이 떨어지고, 로직이 서비스 계층에 분산되어 중복될 가능성이 높다
- 도메인 모델링과 개발이 충분히 이루어지지 않은 초기 단계에서는 빈약한 도메인 오브젝트 방식이 더 적절할 수 있지만, 시스템이 복잡해질수록 이 방식의 한계가 드러날 가능성이 크다.
풍성한 도메인 오브젝트 방식
- 특징 : 도메인 오브젝트에 비즈니스 로직을 포함시켜 응집도를 높인다. 로직을 도메인 오브젝트에 담아두면 서비스 계층에서 반복적인 로직 호출 없이 간단하게 사용할 수 있다
- 장점 : 코드의 간결성과 객체지향적 설계가 가능해진다. 서비스 계층에서의 코드 중복을 줄이고, 비즈니스 로직을 보다 쉽게 이해할 수 있다
-
한계 : 도메인 오브젝트는 스프링 빈이 아니므로 DI를 받을 수 없으며, 데이터 액세스와 같은 작업을 직접 수행할 수 없다
- SOFEA 아키텍처
- 프레젠테이션 계층이 클라이언트까지 확장되는 아키텍처로, 클라이언트에서 서버와 통신하며 동작

- 프레젠테이션 계층이 클라이언트까지 확장되는 아키텍처로, 클라이언트에서 서버와 통신하며 동작
- 정보 전송 아키텍처
- 도메인 오브젝트 : 스프링의 기본 기술에 적합한 정보 전송 아키텍처로, 계층 간의 정보 일관성을 유지하는 데 유용함
- 레거시 시스템 전환 : DB 중심의 아키텍처를 스프링으로 전환할 때, 도메인 오브젝트 중심으로 전환하는 것이 바람직함
스프링과 외부 기술의 통합
- 스프링 빈 등록 : 외부 기술의 핵심 오브젝트를 스프링 빈으로 등록하여 DI 방식으로 사용 가능하게 함
- 서비스 추상화 및 템플릿/콜백 적용 : 외부 기술의 인터페이스를 추상화하거나 템플릿/콜백 방식으로 반복적인 코드를 간소화함
- 예외 전환 : 외부 기술에서 발생하는 예외를 AOP를 통해 스프링의 일관된 예외로 전환 가능함
댓글남기기