Spring Boot의 작동 원리에 대해 간략하게 정리하고 넘어가도록 하자.
Spring Boot의 설정 내용들은 Java 클래스를 이용해 처리할 수도 있음. 그러나 resources 폴더 내에 저장되어 있는 파일들 중 application.yml 또는 application.properties라는 파일이 Spring Boot에서 필요한 설정들을 담당함. .properties 확장자 파일을 사용한다면 =로 구분된 설정 이름과 값을 지정할 수 있고(설정 이름 = 값) .yml(또는 yaml) 파일을 사용하면 설정 이름과 값을 :으로 구분해 저장할 수 있음(설정 이름: 값).
.yml(또는 .yaml) 파일을 사용하면 계층 구조로 구분할 수 있기 때문에 같은 이름으로 grouping이 되어 있는 경우 훨씬 더 적은 데이터의 양을 가지고 동일한 속성을 지정할 수 있어 구조적으로 보다 컴팩트한 설정을 할 수 있다는 특징이 있음.
이제 application.properties 또는 application.yml 파일의 설정 내용을 추가해 보려 함. 이전에 생성한 Spring Boot 프로젝트에서 resources 폴더 내에 application.properties라는 파일이 보일 것임. Spring Boot 프로젝트를 처음 생성하면 .properties 파일이 생성되지만 사용의 편의를 위해 확장자를 .yml로 변경해도 됨. 어떤 파일을 쓰든 상관은 없지만 .yml 파일 포맷은 XML이나 Json과 같이 데이터를 저장하기 위한 구조를 나타낼 수 있고 필요로 하는 내용을 grouping할 수 있기 때문에 가독성과 확장성 면에서 좋은 문서 포맷을 만들 수 있어 환경설정 파일에서 자주 사용됨. 따라서 .properties보다는 .yml의 사용을 권장함.
// .properties
server.port = 8088
logging.level.org.springframework = debug
// .yml
server:
port: 8088
logging:
level:
org.springfamework: debug
이제 서버를 기동하여 콘솔창에 출력된 내용을 보면 Spring Framework가 사용하고 있는 Bean의 상태들이 출력되는 것을 확인할 수 있으며 가장 마지막에 Tomcat의 서버 포트는 8088로 변경되어 실행된 것을 확인할 수 있음.
Auto Configuration
Spring Boot에서 실행되는 Auto Configuration에 대해 알아보겠음. 먼저 Spring Boot에서는 사용자의 모든 요청을 처리하기 위해 DispatcherServlet을 사용하는데 이를 관리하기 위해 DispatcherServletAutoconfiguration이라는 Bean을 로딩하고 다음으로 에러 처리를 위해 ErrorMvcAutoConfiguration이라는 Bean을 로딩함. 또한 사용자의 요청에 따른 비즈니스 로직을 처리한 뒤 에는 결과 값을 클라이언트로 전달해 줘야 하는데 이때 응답 데이터 포맷을 변경하기 위해 HttpMessageConvertersAutoConfiguration Bean을 로딩함. HttpMessageConvertersAutoConfiguration은 기본적으로 데이터를 JSON 포맷으로 변환시켜 사용함.
DispatcherServlet
위에서 언급한 것들 외에도 기본적으로 로딩되는 많은 Bean들이 있지만 그중에서도 가장 중요한 DispatcherServlet에 대해 알아보려 함.
‘dispatch’라는 단어의 사전적인 의미는 어떠한 정보나 메시지를 다른 쪽으로 전달한다는 것. DispatcherServlet의 역할 또한 그러하며 자바 웹 프로그래밍뿐 아니라 Spring MVC, Spring Boot에서의 DispatcherServlet은 일단 Servlet Application을 실행할 수 있는 환경(Servlet Container)에서 HTTP 프로토콜을 통해 들어오는 모든 요청을 처리하기 위해서 가장 앞단에서 Front Controller의 역할을 한다고 볼 수 있음. 일종의 게이트 역할인 것. 쉽게 말해 사용자의 모든 요청은 DispatcherServlet에서 시작되어 DispatcherServlet로 끝남.
위 그림과 같이 사용자의 요청은 DispatcherServlet을 거쳐 해당 작업을 하기 위해 Handler Mapping과 Controller 처리를 하게 됨. 그리고 처리된 결과에 따라 Spring MVC에서는 Model 형태로 반환해 주면서 해당하는 값을 사용자에게 보여주는 View를 렌더링하게 됨. 그리고 마지막으로 사용자에게 보이는 View와 함께 다시 최종적인 값을 전달함. 이러한 모든 과정에서 시작과 끝을 담당하는 것이 DispatcherServlet.
이러한 DispatcherServlet은 클라이언트의 모든 요청을 한 곳으로 받아서 처리하고 알맞는 Handler로 요청을 전달하며 Handler의 실행 결과를 HTTP Response 형태로 만들어서 반환하는 기능을 함.
RestController
Spring MVC에서는 Controller와 Component, Bean 등을 설정 파일에 등록한 후 사용하도록 되어 있었음. 그러나 Spring 4부터는 사용하려고 하는 모든 Bean들을 어노테이션을 통해 등록하도록 지원해 줌. 그래서 @RestController를 선언하면 별도의 작업을 하지 않더라도 이와 같이 선언된 Controller는 RestController로 쓰겠다는 의미로 해석할 수 있게 됨. Spring Boot를 이용해 개발하려고 하는 REST API 서비스는 사용자에게 보여주는 View 형태의 페이지를 별도로 가지고 있지 않은 경우가 대부분이며 XML이나 JSON과 같은 데이터 포맷으로 결과 값을 전달하는 형태의 애플리케이션이 많음. 따라서 클라이언트의 요청 값을 JSON 형식으로 변경하여 전달하는 것만 신경쓰면 됨.
Spring 웹에서는 사용자에게 보여주는 페이지를 가지고 있지 않은 형태의 Controller를 생성할 수 있도록 RestController를 지원하고 있는데 사용자가 RestController 타입을 사용하면 전달하려 하는 메시지나 반환 데이터 값을 ResponseBody에 추가하는 작업을 따로 하지 않더라도 자동으로 ResponseBody에 담겨 반환됨. DispatcherServlet을 통해 클라이언트의 요청을 받은 다음 Handler를 통해 필요로 하는 값을 처리한 뒤 사용자에게 반환시켜 주는 것. 간단히 말해 RestController라는 것은 기존의 Controller에 ResponseBody가 포함되어 있는 형태라고 볼 수 있음.
@RestController
public class HelloWorldController{
// GET
// URI: /hello-world
// @RequestMapping(method=RequestMethod.GET, path="/hello-world")
@GetMapping(path="/hello-world")
public String helloWorld(){
return "Hello World!";
}
@GetMapping(path="/hello-world-bean")
public HelloWorldBean helloWorldBean(){
return new HelloWorldBean("Hello World!");
}
}
지난 예제에서 "Hello World!"라는 값의 반환을 위해 두 개의 API를 작성하였는데 하나는 단순히 텍스트 형식의 문자열을("/hello-world"), 다른 하나는 객체 형태로("/hello-world-bean") 반환시켜 주는 경우가 있었음. 이 두 번째의 경우 원래의 Controller였다면 ResponseBody에 HelloWorldBean을 집어 넣고 반환시켜 줘야 했겠지만, 위와 같이 RestController를 쓰고 있는 상황이라면 HelloWorldBean 자체가 자동으로 ResponseBody에 포함되어 반환시키도록 해 주는 것.
위의 HelloWorldController에 @RestController가 아닌 @Controller가 선언되어 있었다면 helloWorldBean()은 아래와 같이 쓰일 수 있음.
@Controller
public class HelloWorldController{
@GetMapping(path="/hello-world-bean")
public @ResponseBody HelloWorldBean helloWorldBean(){
return new HelloWorldBean("Hello World!");
}
}
출처
본 포스트는 인프런 이도원 강사님의 "Spring Boot 3.x 를 이용한 RESTful Web Services 개발" 강의를 참고해 직접 작성 및 정리한 글입니다.
'Java > Spring' 카테고리의 다른 글
[Spring Boot] Path Variable - 가변 URI 사용 (1) | 2024.09.19 |
---|---|
[Spring Boot] Hello World Bean (0) | 2024.09.11 |
[Spring Boot] HelloWorld Controller (1) | 2024.09.02 |
[Spring Boot] Spring Boot 프로젝트의 구조와 실행 방법 (1) | 2024.08.30 |
Restful API 설계 (2) | 2024.08.28 |