Spring Boot Directory

들어가기전

Yun Blog님 블로그를 참고하였습니다 저의 멋대로 정리한 것임으로.. 자세한 내용은 Yun Blog님 블로그를 보시길 권장드립니다.

패키지 구성의 2가지 유형

  • 계층형 : 각 계층을 대표하는 디렉터리를 기준으로 코드를 작성

    └── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── example
    │   │           └── demo
    │   │               ├── DemoApplication.java
    │   │               ├── config
    │   │               ├── controller
    │   │               ├── dao
    │   │               ├── domain
    │   │               ├── exception
    │   │               └── service
    │   └── resources
    │       └── application.properties
    

    장단점

    • (장) 해당 프로젝트에 이해가 상대적으로 낮아도 전체적인 구조를 빠르게 파악 가능
    • (단) 디렉터리에 클래스들이 너무 많이 모이게 되는 점
  • 도메인형 : 도메인 디렉터리 기준으로 코드 구성

    └── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── example
    │   │           └── demo
    │   │               ├── DemoApplication.java
    │   │               ├── coupon
    │   │               │   ├── controller
    │   │               │   ├── domain
    │   │               │   ├── exception
    │   │               │   ├── repository
    │   │               │   └── service
    │   │               ├── member
    │   │               │   ├── controller
    │   │               │   ├── domain
    │   │               │   ├── exception
    │   │               │   ├── repository
    │   │               │   └── service
    │   │               └── order
    │   │                   ├── controller
    │   │                   ├── domain
    │   │                   ├── exception
    │   │                   ├── repository
    │   │                   └── service
    │   └── resources
    │       └── application.properties
    

    장단점

    • (장) 관련된 코드들이 응집
    • (단) 프로젝트에 이해도가 낮을 경우 전체적인 구조를 파악하기 어려움

도메인형이 더 좋아!

간단한 프로젝트라면 모르겠지만 프로젝트가 복잡도에 따라 계층형 구조에서는 한개의 패키지에 적게는 30 ~ 40의 클래스들이 xxxController, xxxService 같이 비슷한 패턴으로 나열된다.
하지만 도메인형은 관련된 코드들끼리 응집해 있음으로 이런 문제를 피할 수 있다.

프로젝트를 진행하며 각 도메인에 대한 이해도가 올라감으로 도메인형 구조의 단점은 금방 해결된다.

최종 구조!

└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── example
    │   │           └── project
    │   │               ├── ApiApp.java
    │   │               ├── SampleApi.java
    │   │               ├── domain
    │   │               │   ├── coupon
    │   │               │   │   ├── api
    │   │               │   │   ├── application
    │   │               │   │   ├── dao
    │   │               │   │   ├── domain
    │   │               │   │   ├── dto
    │   │               │   │   └── exception
    │   │               │   ├── member
    │   │               │   │   ├── api
    │   │               │   │   ├── application
    │   │               │   │   ├── dao
    │   │               │   │   ├── domain
    │   │               │   │   ├── dto
    │   │               │   │   └── exception
    │   │               │   └── model 
    │   │               │       ├── Address.java
    │   │               │       ├── Email.java
    │   │               │       └── Name.java
    │   │               ├── global
    │   │               │   ├── common
    │   │               │   │   ├── request
    │   │               │   │   └── response
    │   │               │   ├── config
    │   │               │   │   ├── SwaggerConfig.java
    │   │               │   │   ├── properties
    │   │               │   │   ├── resttemplate
    │   │               │   │   └── security
    │   │               │   ├── error
    │   │               │   │   ├── ErrorResponse.java
    │   │               │   │   ├── GlobalExceptionHandler.java
    │   │               │   │   └── exception
    │   │               │   └── util
    │   │               └── infra
    │   │                   ├── email
    │   │                   └── sms
    │   │                       ├── AmazonSmsClient.java
    │   │                       ├── SmsClient.java
    │   │                       └── dto
    │   └── resources
    │       ├── application-dev.yml
    │       ├── application-local.yml
    │       ├── application-prod.yml
    │       └── application.yml

각 Directory 설명

Model
model 
├── Address.java
├── Email.java
└── Name.java

Domain Entity 객체들이 공통적으로 사용할 객체들로 구성 주로 Embeddable, Enum, 상위 Entity 객체

Member (각 Domain들)
member
├── api
│   └── MemberApi.java
├── application
│   ├── MemberProfileService.java
│   ├── MemberSearchService.java
│   ├── MemberSignUpRestService.java
│   └── MemberSignUpService.java
├── dao
│   ├── MemberFindDao.java
│   ├── MemberPredicateExecutor.java
│   ├── MemberRepository.java
│   ├── MemberSupportRepository.java
│   └── MemberSupportRepositoryImpl.java
├── domain
│   ├── Member.java
│   └── ReferralCode.java
├── dto
│   ├── MemberExistenceType.java
│   ├── MemberProfileUpdate.java
│   ├── MemberResponse.java
│   └── SignUpRequest.java
└── exception
    ├── EmailDuplicateException.java
    ├── EmailNotFoundException.java
    └── MemberNotFoundException.java
  • api : ControllerClass의 위치
    주로 rest api 프로젝트를 구성하는 경우가 많아 줄여서 api라고 명시
  • domain : Domain Entity Class의 위치 추가로 특정 Domain에만 속하는 Embeddable, Enum도 포함
  • dto : dto Class의 위치
  • exception : domain에서 발생시키는 exception class의 위치
  • application: service 계층
  • dao : repository, dao계층, 사실 두개는 나눌만큼 차이가 있다고 판단되지 않아서 나누지 않기로 했다.
    그렇게 생각하게 된 출처
global
global
├── common
│   ├── request
│   └── response
├── config
│   ├── SwaggerConfig.java
│   ├── properties
│   ├── resttemplate
│   └── security
├── error
│   ├── ErrorResponse.java
│   ├── GlobalExceptionHandler.java
│   └── exception
└── util

프로젝트 전반에 걸쳐서 사용되는 객체 혹은 설정 값을 구성한다.

  • common : 공통으로 사용하는 DAO같은 객체 사용
  • config : 스프링 각종 설정 파일
  • error : 예외 Exception
    cheese10yum님의 Exception Guild를 참고
  • util : Util Class
infra
infra
├── email
└── sms
    ├── AmazonSmsClient.java
    ├── SmsClient.java
    └── dto

이메일, SMS, WebHook 등 외부 서비스에 대한 코드들이 존재
이런 외부 코드는 사용하는 서비스에 따라서 쉽게 변경되고 지워질 수 있기 때문에 따로 분리하는게 좋다.

comments powered by Disqus