스프링 부트는 다음 그림과 같이 각 계층이 양 옆 계층과 통신하는 구조를 따른다.
여기서 계층이란 각자의 역할과 책임이 있는 어떤 소프트웨어의 구성 요소를 의미한다. 각 계층은 서로 소통할 수는 있지만 다른 계층에 직접 간섭하거나 영향을 미치지는 않는다.
스프링 부트에는 프레젠테이션, 비즈니스, 퍼시스턴스 계층이 존재한다. 각 계층들이 서로 통신하면서 프로그램을 구성하고 있다.
Presentation 계층 (Controller)
HTTP 요청을 받고 이 요청을 비즈니스 계층으로 전송하는 역할을 한다. 컨트롤러가 프레젠테이션 계층의 역할을 하고, 스프링 부트 내에 여러개가 존재할 수 있다.
Business 계층 (Service)
모든 비즈니스 로직을 처리한다. 비즈니스 로직이란 서비스를 만들기 위한 로직을 의미한다. Persistence 계층에서 제공하는 서비스를 사용할 수도 있고, 권한을 부여하거나 유효성 검사를 할 수도 있다. 서비스가 비즈니스 계층의 역할을 한다.
Persistence 계층 (Repository)
모든 데이터베이스 관련 로직을 처리한다. 이 과정에서 데이터베이스에 접근하는 DAO 객체를 사용할 수도 있다.
- DAO 객체
Data Access Object의 약자로, 데이터베이스 계층과 상호작용하기 위한 객체이다. DB에 접근하기 위한 로직을 분리하기 위해 사용한다. 직접 DB에 접근하여 data를 삽입, 삭제, 조회 등 조작할 수 있는 기능을 수행한다. MVC 패턴의 Model에서 이러한 일을 수행한다.
- DTO 객체
Data Transfer Object의 약자로, 계층 간(Controlelr, View, Business Layer) 데이터 교환을 위한 Java Bean을 의미한다. DTO는 로직을 가지지 않는 데이터 객체이고, getter, setter 메소드만 가진 클래스를 의미한다.
핵심은 계층은 개념의 영역이고, 컨트롤러, 서비스, 리포지토리는 실제 구현을 위한 영역이라는 것이다.
main
실제 코드를 작성하는 공간이다. 프로젝트에 필요한 소스 코드나 리소스 파일은 모두 이 폴더 안에 존재한다.
test
프로젝트의 소스 코드를 테스트를 할 목적의 코드나 리소스 파일이 존재한다.
build.gradle
빌드를 설정하는 파일이다. 의존성이나 플러그인 설정 등과 같이 빌드에 필요한 설정을 할 때 사용한다.
setting.gradle
빌드할 프로젝트의 정보를 설정하는 파일이다.
main 디렉토리는 java와 resource로 구성되어 있다.
java 디렉토리 구성
각 계층별 코드가 구현되어 있는 곳이다. 컨트롤러, 서비스, 리포지토리 등으로 구현될 수 있다.
resource 디렉토리 구성 (다음 구성들이 없을 시 생성)
- resource - templete : HTML과 같은 뷰 관련 파일로 구성
- static : JS, CSS, 이미지와 같은 정적 파일로 구성
- application.yml (application.properties) : 스프링 부트 설정을 하는 파일로, 서버가 실행되면 자동으로 로딩된다.
- application.yml과 application.properties 차이
Spring Initializr를 통해 Spring Boot 프로젝트를 생성하면 application.properties가 생성이 된다. 하는 역할은 둘 다 같지만, 내부적인 구조가 다르다.
properties의 경우엔 각 줄마다 key=value의 형태로 이루어져 있지만, yml의 경우엔 들여쓰기로 구분되는 계층 구조 및 key: value의 형태로 이루어져 있다.
결론적으로 둘 중 어떤 것을 사용해도 문제가 없지만 properties와 yml을 함께 사용하면 properties 파일이 우선순위가 높아 yml 파일에서 설정한 내용이 덮어씌워질 수 있다는 점이다. 따라서 되도록이면 둘 중 한쪽만 사용하는 것이 권장된다.
Postman에서 Tomcat에 /test GET 요청 후 요청이 스프링 부트 내로 이동
스프링 부트의 디스패처 서블릿이 URL을 분석 후, 요청을 처리할 수 있는 컨트롤러를 탐색.
해당 컨트롤러(TestController)가 /test라는 path에 대한 GET 요청을 처리할 수 있는 getAllMembers() 메소드를 가지고 있으므로 디스패처 서블릿이 TestController에게 /test GET 요청을 전달.
/test GET 요청을 처리할 수 있는 getALLMembers() 메소드와 매치. getAllMembers() 메소드에서는 Business 계층과 Persistence 계층을 통하면서 필요한 데이터를 가져온다.
View Resolver는 템플릿 엔진을 사용해 HTML 문서를 만들거나 JSON, XML 등의 데이터를 생성한다.
그 결과 members를 return 하고 데이터를 Postman에서 확인할 수 있다.