도림.로그

Tags

Series

About

[Spring 공부] 김영한님의 입문 강의 - 1

2022. 02. 16.

Spring Study

▶ Expand post list

    Spring Boot를 처음 공부하는 사람이 공부한 내용을 정리해서 작성한 포스트입니다. 오개념 및 오류가 있을 수 있으니, 발견하신다면 가감없이 댓글을 통해서 알려주세요! 확인하는 대로 정확한 정보를 확인해서 고치도록 하겠습니다.

    개요

    이번 Spring Boot 스터디는 배달의 민족의 김영한님께서 인프런에 올려주시는 자바 스프링 완전 정복 시리즈를 기반으로 진행한다. 그 시리즈의 가장 첫 강의인 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술을 들어보고 간단히 정리해보고자 한다.

    해당 강의는 내가 느끼기에 크게 다음의 컨텐츠를 가지고 있었다.

    • Spring 기초 기능 써보기
    • Spring Bean과 의존 관계
    • 회원 관리 예제 구현하기
      • Controller - Service - Repository 패턴 적용
      • Spring MVC 적용
    • 위의 예제에 다양한 DB 접근 기술 적용
      • JDBC
      • JDBC Template
      • JPA
      • Spring Data JPA
    • 위의 예제에 간단한 AOP 적용

    이 포스트에서는 Spring 기초 기능 써보기에 대해서 정리해보도록 하겠다.

    Spring 기초 기능 써보기

    해당 강의는 Spring Boot의 개발 프로세스를 가볍게 쓱 훑고 지나가는 것에 있다 보니, 강의중에 상세한 설명보다는 개괄적인 설명을 통해서 느낌적인 느낌을 전달하면서 강의가 진행이 된다.

    정적 컨텐츠

    Spring Boot에서 정적 컨텐츠를 서빙하고 싶으면 단순하게 resources/static/ 디렉토리에 컨텐츠를 넣어주면 된다. 그러면 Spring이 뜰 때 이를 자동으로 정적 컨텐츠로 인식하여 서빙해준다.

    이에 접근하고 싶으면 기본 설정상으로는 그냥 http://<domain>/<static-content-name> 의 형태로 접근할 수 있는 것으로 보인다.

    MVC와 Template Engine

    MVC는 데이터를 관리하는 Model과 사용자에게 보이는 부분을 관리하는 View, 그리고 이 둘 사이를 얇게 연결하는 Controller로 구성된 패턴이다. 이에 대한 설명은 다음에 다뤄보는 것으로 하고, Spring에서는 이 패턴을 적극적으로 활용하는 Spring MVC라는 것이 있는 것으로 알고 있다.

    일단 이 MVC의 예시를 보여주기 위해 강의상에서 Template Engine인 ThymeLeaf를 사용한다. Template Engine은 html을 동적으로 생성해주기 위한 엔진으로 어떠한 Template에다 외부에서 데이터를 넣어주어 그것을 통해서 동적으로 html을 생성하게 된다.

    그리고 Controller를 작성해주게 되는데, Spring Boot 프로젝트에서 SpringBootApplication 이 있는 패키지 안에 controller 라는 패키지를 생성하고, 그 안에 <name>Controller 의 형태로 Controller 클래스를 생성한다. 강의에서는 HelloController 라는 이름으로 생성하였다. 그리고 다음과 같이 작성한다.

    @Controller
    public class HelloController {
        @GetMapping("hello-mvc")
        public String helloMvc(@RequestParam("name") String name, Model model) {
            model.addAttribute("name", name);
            return "hello-template";
        }
    }

    Spring 공부를 하다 보면 마치 마법과 같이 느껴지는 것들이 많이 있는데, 그 중 하나가 바로 위의 코드에서 사용한 어노테이션(Annotation)들이다. @<annotation-name> 또는 @<annotation-name>(...args) 의 형태로 사용하는데, 이것들이 아래에 구현된 클래스에 특정 기능이나 동작 등을 부여해서 특정 목적에 부합하게 동작하도록 만들어 준다.

    위의 코드의 경우 @Controller@GetMapping("hello-mvc") 그리고 @RequestParam("name") 가 사용되었는데, @Controller 는 그저 public class인 HelloController 를 Spring 위에서 올바르게 동작하는 Controller로 만들어주고,

    @GetMapping("hello-mvc") 는 HTTP GET 요청이 /hello-mvc 로 들어올 경우 아래의 함수가 실행될 수 있도록 Mapping 해준다. 심지어, @RequestParam("name") 는 URL Parameter에서 name을 알아서 뽑아내서 그것을 함수 파라미터 name에 넣어준다. 이런 것들을 우리가 직접 구현하는 것이 아니라 그냥 적절한 어노테이션을 가져다 쓰면 앵간해서는 최적화된 형태로 마법같이 구현되는 것이 Spring의 강점이지 않나 싶었다.

    어쨌든, Controller의 특정 Mapping된 메소드에서는 String 형태의 무언가를 반환하는데, 이것은 바로 우리가 만들고자 하는 Template의 파일 이름, 즉 View의 파일 이름이다. 저걸 String 형태로 반환해주면 (물론 굉장히 복잡한 세부적 구현이 있겠지만 지금 단계에서는) Spring이 알아서(ㅋㅋ) 해당 Template을 불러와서 적절한 Template Engine을 실행해 HTML을 작성하여 사용자에게 반환하게 된다.

    아, 저 Controller 메소드 안의 model이 뭐냐고? 정확하게 강의에 나오지는 않지만 ThymeLeaf에서 사용하는 데이터인 듯 하다. 위의 코드에서는 name 이라는 attribute를 model에 넣어주었는데, 이를 Template 상에서 다음과 같이 활용한다.

    <html xmlns:th="http://www.thymeleaf.org">
      <body>
        <p th:text="'hello ' + ${name}">hello! empty</p>
      </body>
    </html>

    여기서 html attribute로 th: 라고 되어있는 것들이 있는데, 이녀석들이 바로 ThymeLeaf Template Engine을 사용하는 녀석들이다. 그리고 거기 보면 ${name} 으로 name이라는 녀석을 가져다 쓰는 것을 볼 수 있다. 그렇다, 이 name 이 위의 Controller에서 model의 attribute로 추가해준 그 녀석이다.

    API

    최근에는 Spring MVC 처럼 서버에서 html을 완전히 작성해서 돌려주는 SSR 방식 이외에도 React나 Vue처럼 클라이언트 상에서 서버로부터는 데이터만 전달받아 렌더링하는 CSR 방식, 혹은 이 둘을 적절히 섞어서 사용하는 방식들도 많이 쓰이고 있다.

    엄밀하게 말하자면 API는 이보다 더 많은 의미를 가지고 있지만, 쉽게 생각해서 API 서버를 만든다고 하면 저런 곳에 사용하기 위한 데이터를 사용자에게 반환해주는 서버를 만드는 것이다.

    Spring에서도 당연히 API 서버를 간단하게 만들 수 있는 방법을 제공한다. Controller의 메소드를 작성할 때 @ResponseBody 라는 어노테이션 하나만 붙여주면 끝이다.

    @Controller
    public class HelloController {
        @GetMapping("hello-string")
        @ResponseBody
        public String helloString(@RequestParam("name") String name) {
            return "hello " + name;
        }
    }

    그러면 Spring에서 문자열을 반환하더라도, 그 문자열에 해당하는 View를 찾으려고 하지 않고 저 문자열 자체를 사용자에게 반환하게 된다. 그런데 보통 API 서버에 요청을 보낼 경우 대개 JSON 형태로 응답을 받게 된다. 위 처럼 그냥 문자가 아니라 JSON을 반환하고 싶다면 어떻게 해야할까?

    @Controller
    public class HelloController {
        @GetMapping("hello-api")
        @ResponseBody
        public Hello helloApi(@RequestParam("name") String name) {
            Hello hello = new Hello();
            hello.setName(name);
            return hello;
        }
    
        static class Hello {
            private String name;
            public String getName() {
                return name;
            }
    
            public void setName(String name) {
                this.name = name;
            }
        }
    }

    간단하다. 그냥 객체 만들어서 인스턴스 하나 생성하고, 그 인스턴스를 반환하면 된다. 그러면 그 객체를 Spring에서 JSON 형태로 직렬화(Marshalling)하여 사용자에게 반환해준다. Go 언어에서 데이터를 JSON 형태로 만들려고 난리를 쳤던 경험이 너무나도 허무해지는 순간이었다.

    다음은

    다음 포스트에서는 Spring Bean과 의존 관계에 대한 강의 내용을 간략히 정리해보도록 하겠다.

    끝.

    #java#spring#inflearn#spring boot

    © 2024, Built with Gatsby