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
:Controller
Class의 위치
주로rest api
프로젝트를 구성하는 경우가 많아 줄여서 api라고 명시domain
: DomainEntity
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 등 외부 서비스에 대한 코드들이 존재
이런 외부 코드는 사용하는 서비스에 따라서 쉽게 변경되고 지워질 수 있기 때문에 따로 분리하는게 좋다.