Web/Java+Spring

Layered Architecture

WakaraNai 2021. 6. 7. 22:21
728x90
반응형

Controller에서 중복되는 부분

- 헤더의 로그인 버튼, 검색창

- 광고 배너

 

Controller에서 중복되는 부분을 처리하려면?

  • 별도의 객체로 분리합니다.
  • 별도의 메소드로 분리합니다.
  • 예를 들어 쇼핑몰에서 게시판에서도 회원 정보를 보여주고, 상품 목록 보기에서도 회원 정보를 보여줘야 한다면 회원 정보를 읽어오는 코드는 어떻게 해야 할까요?

 

컨트롤러와 서비스

  • 컨트롤러들이 중복 호출된 부분들을 별도의 객체인 Service로 구현
  • 이 객체는 보통 업무와 관련된 메소드를 가지고 있어, 비즈니스 메소드라고 함
    • 이런 서비스 객체란 비즈니스 로직을 수행하는 메소드를 가진 객체를 말함
    • 하나의 비즈니스 로직은 하나의 트랜잭션으로 동작
  • 컨트롤러는 Service객체를 사용하도록 합니다.
    • 상품 서비스의 경우, 컨트롤러 1번, 컨트롤러 2번도 이용하는 것을 볼 수 있음
    • 이 경우, 컨트롤러 1이나 3에 각각 구현하지 않고
    • 상품 관련 비즈니스만 처리하는 서비스 객체를 따로 만들어 놓고
    • 컨트롤러 1도, 컨트롤러 3도 사용하도록 하게 함

 

 

서비스(Service)객체란?

비지니스 로직(Business logic)을 수행하는 메소드를 가지고 있는 객체를 서비스 객체라고 합니다.

보통 하나의 비지니스 로직은 하나의 트랜잭션으로 동작합니다.

 

트랜잭션(Transaction)이란?

하나의 논리적인 작업을 의미

 

트랜잭션의 특징은 크게 4가지로 구분됩니다.

  1. 원자성 (Atomicity)
    1. 전체가 성공하거나 실패
      1. 예로, 출금할 때 잔액이 충분하면, 출금액만큼 뺀 금액으로 수정 후, 출금 기록을 통장에 기록 후, 출금 실행
      2. 그런데 출금 금액이 적으면, 중간에 오류가 발생 시 모든 일이 일어나지 않아야 함
    2. rollback 하거나 commit을 하면 하나의 트랜젝션 처리가 완료됨
      1. 처음의 상태로 되돌리는 작업을 rollback이라고 함
      2. 문제 없이 다 수행하여 정보를 반영하면 commit 한다고 함
  2. 일관성 (Consistency)
    1. 트랜잭션의 작업 처리 결과가 항상 일관성이 있어야 한다
    2. 트랜잭션 중 데이터가 변경되어도, 새 데이터가 아닌
    3. 처음 트랜잭션을 시작했을 때 참조한 데이터로 진행해야 함
  3. 독립성 (Isolation)
    1. 둘 이상의 트랜잭션이 동시에 병행 실행되면,
    2. 어느 하나의 트랜잭션이라도 다른 트랜잭션의 연산에 끼어들 수 없다.
    3.  하나의 특정 트랜잭션이 완료될 때까지 다른 트랜잭션이 특정 트랜잭셩의 결과를 참조할 수 없다
      1. A 사용자가 하는 작업들을 commit하거나 rollback을 완료하기 전까지
      2. B 사용자는 해당 부분에 대해서 알 수 없음
      3. MySQL 콘솔창을 두 개 열어놓고 테스트해보면 먼저 열었던 창에서 입력한 내용이 완료되지 않는 한, 두번째로 연 콘솔에서는 적용되지 않는 것을 볼 수 있음
  4. 지속성 (Durability)
    1. 트랜잭션이 성공적으로 완료됐을 때 결과가 영구적으로 반영됨
    2. 이런 처리를 JDBC에서 Connection conn 객체에서 setAutoCommit()을 이용해 얻어냄
      1. 이 메소드의 기본값은 true이므로 별도의 commit 명령을 수행하지 않아도 DB에 반영됨
      2. 지금처럼, 여러 개의 작업이 끝나야만 or 모두 성공해야만 commit 반영하겠다고 하면
        1. 해당 메소드에 false를 파라미터로 적어줌
      3. 입력, 수정, 삭제 SQL이 실행을 한 후 모두 성공했을 경우 Connection이 가지고 있는 commit()메소드 호출

 

 

@EnableTransactionManagement

  • Spring Java Config파일에서 트랜잭션을 활성화 할 때 사용하는 어노테이션
  • Java Config를 사용하게 되면 PlatformTransactionManager 구현체를 모두 찾아서 그 중에 하나를 매핑해 사용
  • 특정 트랜잭션 메니저를 사용하고자 한다면
    • TransactionManagementConfigurer를 Java Config파일에서 구현하고 원하는 트랜잭션 매니저를 리턴하게 함
    • 아니면, 특정 트랜잭션 매니저 객체를 생성 시 @Primary 어노테이션을 지정

 

서비스 객체에서 중복으로 호출되는 코드(query)의 처리

  • 중복 호출되는 경우
    • 서비스 객체마다 비즈니스 메소드를 갖고 있고,
    • 하나의 비즈니스 메소드는 보통 트랜잭션 단위로 작업이 처리됨
      • 하나의 트랜잭션에는 여러 개의 DB 작업이 수행될 수 도 있음
      • 이때 비즈니스 메소드마다 중복되는 기능을 호출하기도 함
      • 이럴 때 별도의 객체로 분리하거나, 별도의 메소드로 분리해서 사용해야 함
  • Presentation Layer
    • 컨트롤러 객체가 동작
    • 웹에서 화면에 나오는 부분. 
      • Window 프로그램으로 바꾸려할 때 Service, Repository Layer는 그대로 두고 이곳만 바꾸면 됨
  • Service Layer
    • 비즈니스 메소드를 가진 서비스 객체는 동작X
    • 그저 실제 DB에 접근해서 데이터를 가져오는 등의 일만 수행
  • Repository Layer
    • Service 객체는 해당 레이어의 DAO 객체를 사용
  • 데이터 엑세스 메소드를 별도의 Repository(Dao) 객체에서 구현하도록 하고
  • Service는 Repository객체를 사용하도록 합니다.

레이어드 아키텍쳐

 

 

설정의 분리

  • Spring 설정 파일을 프리젠테이션 레이어쪽과 나머지를 분리할 수 있습니다.
  • web.xml 파일에서 프리젠테이션 레이어에 대한 스프링 설정은
    • DispathcerServlet이 읽도록 하고, 그 외의 설정은 ContextLoaderListener를 통해서 읽도록 합니다.
  • DispatcherServlet을 경우에 따라서 2개 이상 설정할 수 있는데
    • 이 경우에는 각각의 DispathcerServlet의 ApplicationContext가 각각 독립적이기 때문에
    • 각각의 설정 파일에서 생성한 빈을 서로 사용할 수 없습니다.
  • 위의 경우와 같이 동시에 필요한 빈은
    • ContextLoaderListener를 사용함으로써 공통으로 사용하게 할 수 있습니다.
  • ContextLoaderListener와 DispatcherServlet은 각각 ApplicationContext를 생성하는데,
    • ContextLoaderListener가 생성하는 ApplicationContext가 root 컨텍스트가 되고
    • DispatcherServlet이 생성한 인스턴스는 root컨텍스트를 부모로 하는 자식 컨텍스트가 됩니다.
  • 참고로, 자식 컨텍스트들은 root컨텍스트의 설정 빈을 사용할 수 있습니다.
728x90
반응형