5 min read

[Spring ๊ณต๋ถ€] ๊น€์˜ํ•œ๋‹˜์˜ ์ž…๋ฌธ ๊ฐ•์˜ - 1

Table of Contents

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๊ณผ ์˜์กด ๊ด€๊ณ„์— ๋Œ€ํ•œ ๊ฐ•์˜ ๋‚ด์šฉ์„ ๊ฐ„๋žตํžˆ ์ •๋ฆฌํ•ด๋ณด๋„๋ก ํ•˜๊ฒ ๋‹ค.

๋.