Table of Contents

개요#

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

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

  • 스프링은 웹브라우저를 클라이언트로 하고 DB에 데이터를 저장, 조회하는데 집중되어 있다.
  • 클라이언트가 반드시 웹브라우저일 필요는 없고 RIA나 HTTP프로토콜을 사용하는 다른 시스템일수도 있다.
  • 백엔드 시스템은 DB뿐 아니라 메시징 서버, 메일서버, 메인프레임등 다양하게 사용이 가능하다.
  • 스프링 엔터프라이즈 애플리케이션의 서비스와 협력구조
그림 1-1

애플리케이션 서버#

  • 스프링 애플리케이션을 배포하려면 JavaEE서버가 필요하다.
  • JavaEE서버는 크게 두가지로 분류할 수 있다.

경량급 WAS/서블릿 컨테이너#

  • 톰캣과 제티와 같은 가벼운 서블릿 컨테이너
  • EJB나 리소스 커넥터, WAS가 제공하는 분산 서비스등이 굳이 필요하지 않다면 서블릿 컨테이너로도 충분하다.

WAS#

  • 스프링은 3.0기준으로 J2EE 1.4와 JavaEE 5.0에 완벽히 호환된다. 일부 JavaEE 6.0의 기능을 지원하기도 한다.

스프링 소스 tcServer#

  • 스프링을 개발하는 스프링소스에는 아파치 프로젝트인 HTTPD와 톰캣의 핵심 개발자가 많다.
  • 톰캣 기반으로 엔터프라이즈 스프링 애플리케이션에 최적화된 경량급 애플리케이션 서버인 tcServer를 개발했다.
    • 톰캣에 비교해서 고급서버관리, 배포기능과 진단기능을 추가로 포함하고 있다.

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

https://docs.oracle.com/cd/E19830-01/819-4712/ablgz/index.html

독립 웹 모듈#

  • 스프링은 보통 war로 패키징된 독립 웹 모듈로 배포된다.

엔터프라이즈 애플리케이션#

  • 확장자가 ear인 엔터프라이즈 애플리케이션으로 패키징해서 배포할수도 있다.

백그라운드 서비스 모듈#

  • J2EE 1.4에서 등장한 rar패키징 방법도 있다.
  • rar는 리소스 커넥터를 만들어 배포하는 방식인데 스프링으로 만든 애플리케이션이 UI는 필요없고 서버내에서 백그라운드 서비스처럼 동작할 필요가 있다면 rar모듈로 만들어서 배포할수 있다.

9.2. 개발도구와 환경#

http://en.wikipedia.org/wiki/Java_EE_version_history#Java_EE_5_.28May_11.2C_2006.29

9.2.1. JavaSE와 JavaEE#

JavaSE/JDK#

  • 스프링 3.0은 JavaSE 5 버전에서 추가된 언어와 문법의 특징을 최대한 활용해서 개발했기 때문에 JDK 5.0 이상의 버전이 필요하다.
  • JDBC 4.0과 같은 일부 기능은 JDK 6.0 이상에 추가된 기능이라 JDK 6.0 이상을 사용해야 한다.

JavaEE/J2EE#

  • 스프링 3.0은 J2EE 1.4나 JavaEE 5.0 이 필요하다.
  • 스프링 3.0 자체는 JDK 6.0과 Java 5.0 을 기준으로 개발됐지만 주요 기능은 JDK 5.0 에서 동작하도록 J2EE 1.4버전과 호환된다.
  • 다만 J2EE 1.4 버전 서버를 사용할때는 JDK 5.0에서 동작하는지 반드시 확인이 필요하다.

카페에서는#

  • 톰캣 6.0을 사용함
    • http://tomcat.apache.org/tomcat-6.0-doc/index.html
    • Servlet 2.5 과 JavaServer Pages 2.1 를 지원하기 때문에 JavaEE 5.0을 사용함

9.2.2. IDE#

  • 이클립스
  • 넷빈즈
  • 인텔리제이

9.2.3. SpringSource Tool Suite#

  • 스프링 개발에 필요한 플러그인이 포함되어 있다.
  • 스프링 플러그인외에도 개발에 필요한 각종 플러그인이 포함되어 있고 스프링소스에서 필요한 검증을 마치고 릴리즈한다.

SpringIDE 플러그인 #

책에는 스샷이 많음.. 보강하자.
  • 빈 클래스 이름 자동완성
  • 빈 설정 오류검증 기능
  • 프로젝트 생성, 설정파일 생성, 빈 등록 마법사
  • 빈 의존관계 그래프
  • AOP 적용대상 표시
  • 기타 지원기능

STS 플러그인#

  • 스프링 개발과 설정파일 편집을 지원하는 SpringIDE에 더해서 스프링 애플리케이션의 서버 배치와 같은 추가기능을 제공해준다.

기타 플러그인#

  • M2Eclipse : 메이븐 플러그인
  • AJDT : AspectJ Development Tool의 약자로 이클립스에서 AspectJ AOP를 이용한 개발을 지원하는 툴이다.
  • VMCI
  • 이클립스 표준 플러그인 : WTP(Web Tool Platform) 등등

9.2.4. 라이브러리 관리와 빌드 툴#

라이브러리 관리의 어려움#

  • 자바는 모듈이라는 개념이 없다.
    • 같은 패키지와 클래스명을 가진 a.jar, b.jar 가 모두 같은 클래스패스에 있을때 둘중 어떤 것을 사용할지 선택할수 없다.
    • 즉 자바에서 jar파일은 압축 패키징 방법일뿐 구분가능한 독립된 모듈이 아니다.
  • 이런 문제를 해결하기 위해서 가장 간단한 방법은 재패키징이다.
    • C 1.0과 C 2.0 모두 org.library.LibClass 라는 클래스명이라면 그 중 하나를 org.library.repack.LibClass 로 명명한다.
    • 이 클래스를 사용하는 라이브러리도 변경된 패키지의 클래스를 사용하도록 수정해야 한다.
  • 스프링은 의존관계의 문제가 많은 라이브러리의 경우 이런 재패키징 방식을 사용한다.
    • ASM은 버전별로 호환이 안되기로 유명한 라이브러리다.
    • org.springframework.asm 이라는 스프링 패키지 하위로 재패키징했다.

라이브러리 선정#

  • 스프링 모듈
    • 스프링 모듈은 총 20개의 모듈이 있다.
    • 어떤 경우에 어떤 모듈이 필요한지에 대해서는 부록 A.2절의 "스프링 모듈의 의존관계" 를 참고
  • 라이브러리

빌드툴과 라이브러리 관리#

  • 메이븐
  • 앤트(+아이비)

스프링 모듈의 두가지 이름과 리포지토리#

  • 스프링 모듈은 두가지 이름을 가진다. 이름만 다를뿐 같은 파일이다.
  • spring-core-3.0.7.RELEASE.jar
    • 메이븐에 사용하는 명명규칙을 따른 파일이다.
<dependency>
	<groupId>org.springframework</groupId>
	<artifaceId>spring-core</arifaceId>
	<version>3.0.7.RELEASE</version>
</dependency>
  • org.springframework.core-3.0.7.RELEASE.jar
    • OSGI 모듈 명명규칙을 따른 파일이다.
    • 스프링의 모든 모듈은 OSGi 호환모듈로 만들어져 있다.
    • 스프링 배포버전의 dist폴더에 들어있는 모듈 이름도 모두 OSGi 스타일의 이름이다.
    • OSGi 호환이름으로 모듈을 받으려면 메이븐 표준 리포지토리보다는 스프링 소스가 제공하는 번들 리포지토리를 사용해야 함
<repository>
	<id>com.springsource.repository.bundles.release</id>
	<name>SpringSource Enterprise Bundle Repository - SpringSource Bundle Releases</name>
	<url>http://repository.springsource.com/maven/bundles/release</url>
</repository>
<repository>
	<id>com.springsource.repository.bundles.external </id>
	<name>SpringSource Enterprise Bundle Repository - External Bundle Releases</name>
	<url>http://repositorY.springsource.com/maven/bundles/external</url>
</repository>
    • pom.xml 설정도 수정해야 함
<dependency>
	<groupld>org.springframework</groupld>
	<artifactld>org.springframework.core</artifactld>
	<version>3.8.3.RELEASE</version>
</dependency>

9.3. 애플리케이션 아키텍처#

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

9.3.1. 계층형 아키텍처#

아키텍처와 SoC#

  • 지금까지 관심, 책임, 성격, 변하는 이유와 방식이 서로 다른 것들을 분리함으로써 분리된 각 요소의 응집도는 높여주고 결합도는 낮췄다.
  • 지금까지는 오브젝트 레벨에서 분리의 문제를 다뤘다.
    • 성격이 다른 코드는 두개의 오브젝트로 분리하고
    • 그 사이 유연한 결합을 위해 인터페이스를 뒀다.
    • 관계를 맺어주기 위해 DI로 오브젝트간의 직접적인 관계를 알지 못하게 했다.
  • 오브젝트 단위가 아닌 모듈 단위로 확장해보자.
    • 예를들면 DAO의 묶음, 서비스코드의 묶음 등등
    • 오브젝트는 유사한 성격을 지닌 그룹으로 나눌수 있다.
    • 성격이 다른 것은 아키텍처 레벨에서 분리해주는 것이 좋다.
  • 계층적 아키텍처 : 이렇게 책임과 성격이 다른 것을 크게 그룹으로 만들어 분리해두는 것
    • 멀티 티어 아키텍처 라고도 한다.
    • 웹기반의 엔터프라이즈 애플리케이션은 일반적으로 세개의 계정을 갖는다고 해서 3계층(3-tier 또는 3-layer) 애플리케이션이라고도 한다.

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

  • 3계층 아키텍처
그림 9-13
  • 데이터 엑세스 계층
    • 데이터 엑세스 계층의 수직 계층구조
그림 9-14
  • 서비스계층
    • 서비스 계층은 구조로 보자면 가장 단순하다.
    • 대부분 POJO형태로 작성하면 특별한 경우가 아니라면 추상화 수직 계층을 가지지 않는다.
    • 서비스 계층과 기반 서비스 계층
그림 9-16
  • 프리젠테이션 계층
    • 가장 복잡한 계층이다.
    • 프리젠테이션 계층은 매우 다양한 기술과 프레임워크의 조합을 가질수 있다.
    • 프리젠테이션 기술은 끊임없이 나오고 발전한다.
    • 엔터프라이즈 애플리케이션의 프리젠테이션 계층은 HTTP 프로토콜을 사용한다.

계층형 아키텍처 설계의 원칙#

  • 각 계층은 자신의 계층의 책임에만 충실해야 한다.
    • ResultSet이나 SQLException 으로 인해 서비스 코드가 DAO에 종속적으로 되는 코드다.
public ResultSet findUsersByName(String name) throws SQLException;
    • 종속을 제거하기 위해서는 다음처럼 의존성을 가지는 참조를 제거하도록 한다.
public List<User> findUsersByName(String name) throws DataAccessException;

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

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

  • 자바 기술이 발전하기 이전의 엔터프라이즈 시스템에서 흔히 볼수 발견할수 있었다.
  • 일부 로직을 PL/SQL과 같은 저장 프로시저 형태로 만든다.
  • 서비스 계층의 의미가 적고 DB처리로직이 집중하는 형태로 2계층 형태를 보이기도 한다.
  • SQL에 집중하고 코드는 적기 때문에 처음에는 개발이 쉬워보인다.
  • 이런 방식은 변화에 취약하다. DB는 변경하기 쉬운 계층이 아니다.
  • SQL이나 저장 프로시저는 테스트 하기가 쉽지 않다.
  • DB중심의 아키텍처
그림 9-17

거대한 서비스 계층 방식#

  • DB에는 부하가 걸리지 않도록 저장 프로시저의 사용을 자제하고 복잡한 SQL을 피한다.
  • DAO의 로직은 그만큼 단순해진다.
  • 주요로직은 서비스 계층의 코드에서 처리한다.
  • 비즈니스 로직이 복잡해지면서 서비스 계층의 코드도 매우 복잡해지고 커진다. 결국 거대한 서비스 계층을 만드는 원인이 된다.
  • 서비스 계층에서 로직이 추가되므로 테스트 하기 쉽다.
  • 핵심로직이 자바코드에 있어서 테스트하기 편함
  • 개발자 개개인의 코딩습관이나 실력에 따라 코드 스타일이 달라서 복잡한 SQL보다 이해하기 힘든 경우도 생긴다.
  • 거대한 서비스 계층의 아키텍처
그림 9-18

9.3.3. 오브젝트 중심 아키텍처#

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

데이터와 오브젝트#

  • 카테고리와 상품이라는 두가지 엔터티
  • 카페고리와 상품모델
그림 9-19
  • 카페고리와 상품 테이블
표 9-1

도메인 오브젝트를 사용하는 코드#

  • Category 오브젝트를 사용하는 메소드
리스트 9-10
  • 도메인 모델을 사용할 경우 calcTotalOfProductPrice 메소드를 공통으로 사용해서 합을 구할수 있다.
  • 데이터 중심일 경우 매번 sum()함수를 사용하는 쿼리를 사용하거나 Map이나 List에서 값을 가져와서 계산하는 복잡한 처리과정을 거쳐야 한다.

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

  • 일관된 의미를 가지고 유연하며 애플리케애션 전반에 공유가능한 도메인 모델로 정보를 다루면 장점이 많다.
    • 코드를 이해하기 쉽고 로직 작성이 수월하다.
    • 코드 재사용성이 높아지고 DAO는 더 작고 효율적으로 만들수 있다.
  • 단점도 있다.
    • 최적화된 SQL을 사용하는 대신에 성능적인 면에서 일정부분 손해를 볼수도 있다.
    • DAO는 서비스 로직을 알지 못하기 때문에 필요한 칼럼만을 사용하기 보다는 범용적으로 칼럼을 다 나열하는 형태를 사용하게 된다.
    • Product와 Category 중 Product 정보만 필요한 경우에도 Category 정보가 셋팅되면 낭비가 발생하거나 관계를 가진 오브젝트에 null 이 설정되기도 한다.
  • 단점을 해결하기 위한 방법
    • 지연된 로딩(Lazy Loading) 기법을 사용하면 일단 최소한의 오브젝트 정보만 읽어두고 관계하고 있는 오브젝트가 필요한 경우에만 동적으로 DB에서 다시 읽어온다.
    • 이상적으로는 JPA, JDO, 하이버네이트, TopLink 와 같은 ORM을 사용하는 것이다. 이런 기술은 기본적으로 지연된 로딩 기능을 제공해서 도메인 오브젝트 생성을 최적화할수 있다.

빈약한 도메인 오브젝트 방식#

  • 도메인 오브젝트에 정보만 있고 정보를 활용하는 아무런 기능도 없다면 온전한 오브젝트라고 보기 힘들다. 이런 오브젝트를 빈약한 오브젝트라고 부른다. 흔히 VO라고 부르는거?
  • 빈약한 도메인 오브젝트의 비즈니스 로직은 서비스 계층에 로직이 들어있다.
  • 빈약한 도메인 오브젝트 방식의 한계는 거대 서비스 계층 방식과 유사하다. 서비스 계층의 메소드에 대부분의 비즈니스 로직이 있어서 로직의 재사용성이 떨어지고 중복 문제가 있다.
  • 빈약한 도메인 오브젝트 방식
그림 9-20

풍성한 도메인 오브젝트 방식#

  • 풍성한 도메인 오브젝트 또는 영리한 도메인 오브젝트는 빈약한 도메인 오브젝트의 단점을 극복하고 객체지향적인 특징을 잘 사용할수 있도록 해준다.
  • 자신의 정보를 활용하는 로직을 담은 도메인 오브젝트
리스트 9-11
  • 서비스 계층에서 도메인 오브젝트로 로직을 가져왔기 때문에 재사용이 편리하다.
  • 서비스 코드를 줄어들고 도메인 오브젝트는 그자체가 역할이 커진다.
  • 자체 로직을 가진 Category 를 사용하는 코드
리스트 9-13
  • 도메인 오브젝트는 DAO 오브젝트를 DI 받을수 없다.
  • 도메인 오브젝트는 스프링이 관리하는 빈이 아니기 때문이다.
  • 수식계산이나 조건에 다른 데이터 변경이나 자신이 가진 정보에 대한 분석 같은 일부 제한된 로직만 도메인 오브젝에 넣고 DAO나 서비스 계층에 의존하는 로직은 넣지 않는다.
  • 풍성한 도메인 오브젝트 방식
그림 9-21

도메인 계층 방식#

  • 풍성한 도메인 모델이라 하더라도 일부 제한적인 로직만을 담을수 있다.
  • 도메인 오브젝트가 스스로 필요한 정보를 DAO를 통해 가져오고 생성이나 변경이 일어나면 직업 DAO에 변경사항을 반영해달라고 요청할수 없을까.?
  • 도메인 오브젝트들이 하나의 독립적인 계층을 이뤄서 서비스 계층과 데이터 엑세스 계층 사이에 존재하게 한다.
  • 도메인 오브젝트가 독립적인 게층을 이뤄서 발생하는 특징
    1. 도메인에 종속적인 비즈니스 로직의 처리는 서비스 계층이 아니라 도메인 계층의 오브젝트 안에서 진행된다.
    2. 도메인 오브젝트가 기존 데이터 엑세스 계층이나 기반 계층의 기능을 직접 활용할 수 있다.
  • 스프링 빈이 아닌 도메인 오브젝트에 DI를 적용하기 위해서 AOP를 적용한다. AspectJ AOP를 사용하면 클래스의 생성자가 호출되면서 이 시점에 스프링 컨테이너에서 빈을 찾아 DI를 해준다. 이로인해 도메인 오브젝트나 서비스 계층이나 데이터 엑세스 계층의 오브젝트를 참조하면서 조금더 다양한 비즈니스 로직을 처리할 수 있다.
  • 도메인 계층 적용으로 도메인 오브젝트와 서비스 계층간의 구분이 모호해지는 문제를 해결하기 위해서는 두가지 방법을 사용할 수 있다.
    1. 철저한 개발 가이드가 필요하다.
    2. 도메인 오브젝트는 도메인 계층을 벋어나지 못하게 한다. 도메인 계층을 벗어날때는 별도로 준비된 정보 전달용 오브젝트를 만든다. 이런 오브젝트를 데이터 전달을 위해 사용한다고 해서 DTO(Data Transfer Object) 라고 부른다. DTO는 상태의 변화를 허용하지 않고 읽기전용으로 만들기도 한다.
  • 도메인 계층 방식
그림 9-22

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

계층형 아키텍처#

  • 3계층 구조는 스프링을 사용하는 엔터프라이즈 애플리케이션에서 가장 많이 사용하는 구조다.
  • 단 3계층은 논리적인 구분일 뿐이고 2계층으로 구성할수도 있으나 계층간의 구분은 명학하게 해야 한다.

정보 전송 아키텍처#

  • 스프링의 기본 기술에 가장 잘 들어맞고 쉽게 적용해볼수 있는 것은 오브젝트 중심 아키텍처의 도메인 오브젝트 방식이다.

상태 관리와 빈 스코프#

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

  • 스프링이 지원하는 기술이란 무슨 의미일까?
    1. 첫째, 해당 기술을 스프링의 DI 패턴을 따라 사용할 수 있다.
    2. 둘째, 스프링의 서비스 추상화가 적용됐다.
    3. 셋째, 스프링이 지지하는 프로그래밍 모델을 적용했다.
    4. 넷째, 템플릿/콜백이 지원된다.

Add new attachment

Only authorized users are allowed to upload new attachments.
« This page (revision-7) was last changed on 16-Dec-2014 01:09 by DongGukLee