각종 후기/우아한테크코스

[우아한 테크코스 3기] LEVEL 2 회고 (91일차)

제이온 (Jayon) 2021. 5. 3.

안녕하세요? 제이온입니다.

 

오늘은 대부분의 시간을 스프링 공부에 썼습니다.

 

 

김영한님의 스프링 입문 강의

사실은 이 입문 강의를 어느 정도 주말에 들으려고 하였으나, 배포 미션때문에 거의 듣지 못했습니다. 그래서 오전부터 듣기 시작해서 H2 데이터베이스 전까지 학습했습니다. 321분의 분량이라서 오늘 다 할 줄 알았는데, 3시간정도 듣고 지쳐서 그만 들었네요 ㅋㅋㅋ. 스프링 강의는 이곳에서 무료로 학습할 수 있으며, 간단히 제가 오늘 새롭게 배운 내용을 정리해 보려고 합니다.

 

 

(1) 스프링 부트 스타터 페이지

저는 기존에는 build.gradle에서 일일이 의존성 추가하고 세팅을 추가하였는데, 스프링 부트 스타터 페이지를 이용하면 알아서 원하는 세팅이 된 프로젝트를 얻을 수 있다고 합니다. 앞으로 혼자 개발할 때는 이 페이지를 이용하면 더욱 편리하겠다는 생각이 들었습니다.

 

 

(2) Welcome Page 기능

이것은 스프링 부트가 제공하는 기능으로 "/static/index.html"을 생성해 두면, "http://localhost:8080"으로 접속할 때 index.html 내용이 렌더링됩니다. 저는 항상 Controller단에서 GetMapping으로 URL을 정한 후, 특정 html 파일 이름을 반환하는 식으로 코드를 짰어서 이 부분은 처음 알았습니다.

 

 

(3) Thymeleaf 템플릿 엔진

저는 머스테시를 사용했었는데, 새로운 템플릿 엔진을 익혀 보았습니다. 아직은 아주 약간만 맛을 본 정도인데, 아래와 같이 html 소스코드를 작성합니다.

 

 

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
 <title>Hello</title>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<p th:text="'안녕하세요. ' + ${data}" >안녕하세요. 손님</p>
</body>
</html>

 

 

아래에서 3번째 줄에 <p th:text> 부분이 있는데, data라는 key에 대응되는 value가 출력됩니다. 예를 들어, data에 대응되는 value가 "제이온"이라면, 화면에는 '안녕하세요. 제이온'이라는 텍스트가 뜨게 됩니다. 다만, 그 옆에 "안녕하세요. 손님" 이건 뜨지도 않는데 왜 쓰는지는 잘 모르겠습니다. 구글링을 약간 해 보니까, 완전 정적이지 않은 메시지일 경우 ${data} 대신 "안녕하세요. 손님"이 출력된다고 합니다. 일단은 디폴트 값으로만 이해중인데, 아시는 분은 댓글 부탁드립니다.

 

 

 

 

위는 템플릿 엔진의 작동 방식인데, 웹 브라우저에서 "localhost:8080/hello" 요청이 오면, 스프링 컨테이너에서 해당 URL이 존재하는지 찾고, 있다면 model에 값을 담아서 viewResolver로 넘겨 줍니다. 그리고 viewResolver는 "tamplates/hello.html"을 찾아서 모델의 값을 적용해 주고 브라우저에 데이터를 전송합니다. 그리고 웹 브라우저는 그 내용을 렌더링하는 것이죠.

 

 

    @GetMapping("hello")
    public String hello(final Model model) {
        model.addAttribute("data", "hello!!");
        return "hello";
    }

 

 

스프링 단에서는 위와 같이 Controller를 정의해 줍니다.

 

 

(4) 정적 컨텐츠

 

 

정적 컨텐츠는 컨트롤러 URL에 없으므로 바로 리소스에 해당 파일이 있는지 확인하고 브라우저에 렌더링합니다.

 

 

(5) API

@ResponseBody를 사용하여 문자를 반환하는 경우와 객체를 반환하는 경우 서로 출력되는 방식이 다릅니다.

 

 

 

 

@ResponseBody는 간단히 말해서 리턴되는 값을 Http Response의 Body 내용으로 매핑하는 것입니다. 아까 @ResponseBody를 사용하지 않는 경우 viewResolver를 통해 html 파일을 찾는다고 하였습니다. 하지만, 이를 사용할 경우 viewResolver가 아니라 HttpMessageConverter에 따라 html 파일을 찾지 않고 데이터를 다르게 매핑합니다.

 

일반 문자열일 경우 그대로 body에 매핑하지만, 객체일 경우 json 형식으로 파싱합니다. 예를 들어 아래와 같은 코드가 있다고 합시다.

 

 

    @GetMapping("hello-api")
    @ResponseBody
    public Hello helloApi(@RequestParam("name") final String name) {
        final Hello hello = new Hello();
        hello.setName(name);
        return hello;
    }

 

 

이것은 다음과 같이 출력됩니다.

 

 

 

 

Hello라는 객체는 필드로 name을 갖는데, 그 값이 json 형태로 출력되는 것이죠.

 

 

(6) 스프링 빈 등록 방식

저는 @Service, @Controller와 같은 자동 의존 관계를 통해서만 스프링 빈에 등록하는 줄 알고 있었는데, 이러한 컴포넌트 스캔 방식 대신에 자바 코드로 스프링 빈을 설정하는 방법을 알게 되었습니다.

 

방법은 간단합니다. SpringConfig라는 클래스를 생성하고, 아래와 같이 코드를 작성하는 것이죠.

 

 

import hello.hellospring.repository.MemberRepository;
import hello.hellospring.repository.MemoryMemberRepository;
import hello.hellospring.service.MemberService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SpringConfig {

    @Bean
    public MemberService memberService() {
        return new MemberService(memberRepository());
    }

    @Bean
    public MemberRepository memberRepository() {
        return new MemoryMemberRepository();
    }
}

 

 

그리고 해당 클래스에 @Configuration 어노테이션을 달고, 빈에 등록할 클래스에 @Bean 어노테이션을 달면 됩니다. 아직까지 빈과 컴포넌트 스캔에 관한 개념은 부족해서 여기까지만 가볍게 이해하고 넘어갔습니다.

 

 

정리

역시 사람들이 극찬한 것처럼 김영한님의 강의력은 상당히 좋았습니다. 여러 개념들을 이해하기 쉽게 잘 설명해 주셨고, 실습을 진행하는 데 있어서 무리가 없었습니다. 저는 완강이후 시간을 조금씩 내서 배웠던 개념을 추가 학습하여 포스팅해 보려고 합니다.

댓글

추천 글