๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ’Š Java & Kotlin & Spring/- spring framework +

[Springboot] IntelliJ๋ฅผ ์ด์šฉํ•˜์—ฌ Springboot + Mysql + Jpa + Lombok ํ”„๋กœ์ ํŠธ Setup ํ›„ Rest API ์„œ๋ฒ„ CRUD ํ…Œ์ŠคํŠธ (MacOS)

by Wonit 2020. 8. 27.

๋ณธ ๊ธ€์€ Springboot์™€ Mysql + Jpa + Lombok ํ”„๋กœ์ ํŠธ๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ ์ž‘์„ฑํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค.

ํ•ด๋‹น ๋ธ”๋กœ๊ทธ์— ์กด์žฌํ•˜๋Š” ๋ชจ๋“  Springboot + Jpa ๊ด€๋ จ ๊ธ€์€ ์ด ๊ธ€์— ์กด์žฌํ•˜๋Š” ๋‚ด์šฉ์„ ์ „์ œ๋กœ ํ•ฉ๋‹ˆ๋‹ค.


์ˆœ์„œ

  1. Springboot Project ์ƒ์„ฑ
  2. Gradle ์˜์กด์„ฑ ์ถ”๊ฐ€
  3. application.properties ์„ค์ •
  4. db table ์ƒ์„ฑ
  5. Lombok ์„ค์ •
  6. ์ฝ”๋“œ ๊ตฌํ˜„ (model, controller, repository ๋ ˆํฌ์ง€ํ† ๋ฆฌ ์ƒ์„ฑ)
  7. CRUD ํ…Œ์ŠคํŠธ

์ˆœ์„œ๋Š” IntelliJ IDE๊ฐ€ ๊น”๋ ค์žˆ๋‹ค๋Š” ์ „์ œ ํ•˜์— ์ง„ํ–‰๋œ๋‹ค.

Springboot Project ์ƒ์„ฑ

์šฐ๋ฆฌ๋Š” Springboot ํ”„๋กœ์ ํŠธ๋ฅผ ์ด์šฉํ•ด์„œ JPA๋ฅผ ํ…Œ์ŠคํŠธํ•  ๊ฒƒ์ด๋ฏ€๋กœ Springboot ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.


์ง์ ‘ Springboot ํŽ˜์ด์ง€์—์„œ ์ƒ์„ฑํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ ์šฐ๋ฆฌ๋Š” IDE ์ž์ฒด์˜ Spring Initializer์„ ํ†ตํ•ด์„œ ์ƒ์„ฑํ•œ๋‹ค.

'

์„ค์ •์€ ๊ฐ„๋‹จํ•˜๊ฒŒ

- Spring Web

- Mysql Driver

- Spring Data JPA

- Lombok

 

๋งŒ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.

๊ทธ๋Ÿผ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ธฐ๋ณธ ํ”„๋กœ์ ํŠธ๊ฐ€ ๋‚˜ํƒ€๋‚˜๊ฒŒ ๋œ๋‹ค.

Gradle ์˜์กด์„ฑ ์ถ”๊ฐ€

Gradle์€ ์˜์กด์„ฑ์„ ๊ด€๋ฆฌํ•ด์ฃผ๋Š” ๋„๊ตฌ์ธ๋ฐ ์šฐ๋ฆฌ๊ฐ€ ๊ธฐ๋ณธ์ ์œผ๋กœ ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•  ์‹œ์ ์— ํ•„์š”ํ•œ ์˜์กด์„ฑ์„ ๋ชจ๋‘ ์ถ”๊ฐ€ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ง€๊ธˆ์€ ๋”ฑํžˆ ์„ค์ •ํ•  ํŒŒ์ผ์ด ์—†์ง€๋งŒ ์•ž์œผ๋กœ ํ•„์š”ํ•œ ๋ชจ๋“  ์˜์กด์„ฑ์„ ์ด build.gradle ํŒŒ์ผ์—์„œ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

ํ˜น์‹œ ๋ชจ๋ฅด๋‹ˆ ์˜ค๋ฅธ์ชฝ gradle ํƒญ์—์„œ reimport๋ฅผ ์‹œ์ผœ์ค€๋‹ค.

applictation.properties ํŒŒ์ผ ์„ค์ •

applictation.properties์—๋Š” ์ฝ”๋“œ์˜ ์ œ์•ฝ ์‚ฌํ•ญ ๋ฐ database ์„ค์ •๊ณผ JUnit ์„ค์ •, ๋“ฑ๋“ฑ ๋‹ค์–‘ํ•œ ์„ค์ •์˜ Format์œผ๋กœ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค.

 

์ด๋ฒˆ์—๋Š” ์šฐ๋ฆฐ Mysql๋งŒ ์„ค์ •ํ•  ๊ฒƒ์ด๋ฏ€๋กœ Mysql ์„ค์ •์„ ์ถ”๊ฐ€ํ•ด์ฃผ๋„๋ก ํ•œ๋‹ค.

 

Mysql ์„ค์ •์— ํ•„์š”ํ•œ ๋ณ€์ˆ˜๋“ค์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  1. spring.datasource.url : ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค url
  2. spring.datasource.username : ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค username ์•„๋งˆ default๋กœ root๊ฐ€ ์„ค์ •๋˜์–ด์žˆ์ง€ ์•Š์„๊นŒ ์‹ถ๋‹ค.
  3. spring.datasource.password : ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค password
  4. spring.datasource.driver-class-name : ๋“œ๋ผ์ด๋ฒ„ ์ •๋ณด

๋‚˜๋จธ์ง€๋Š” ํ•„์ˆ˜ ์„ค์ •๊นŒ์ง„ ์•„๋‹ˆ๊ณ  ์žˆ์œผ๋ฉด ์ข‹์€ ์„ค์ •์ด๋‹ˆ ํ•„์š”์— ๋”ฐ๋ผ ๊ฒ€์ƒ‰ํ•ด์„œ ์„ค์ •ํ•˜๊ธธ ๋ฐ”๋ž€๋‹ค.

DB ํ…Œ์ด๋ธ” ์„ค์ •

์ด์ œ mysql workbench๋กœ ๋“ค์–ด๊ฐ€์„œ ํ…Œ์ด๋ธ”์„ ๋งŒ๋“ค์–ด๋ณด์ž.


mysql workbench๊ฐ€ ์—†๋‹ค๋ฉด ๊ฐ„๋‹จํ•œ ๋‚ด์šฉ์ด๋‹ˆ ๊ฒ๋จน์ง€ ๋ง๊ณ  ๊ตฌ๊ธ€๋ง ํ•ด์„œ ๊น”์•„๋ณด๋„๋ก ํ•˜์ž.

 

mysql workbench์—์„œ ํ…Œ์ŠคํŠธ ์šฉ๋„์ธ userํ…Œ์ด๋ธ”์„ ๋งŒ๋“ค์–ด๋ณด์ž.

create table์—์„œ User๋ผ๋Š” ์ด๋ฆ„์˜ ํ…Œ์ด๋ธ”์— Id, username, password ๋งŒ ์ถ”๊ฐ€ํ•ด๋ณด์ž.

Lombok ์„ค์ •

๋กฌ๋ณต์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์„ค์น˜ํ•˜๊ณ  ํ™˜๊ฒฝ ์„ค์ •์—์„œ Enable Annotation Process๋ฅผ ์ฒดํฌํ•˜๋„๋ก ํ•˜์ž.

๊ทธ๋ฆฌ๊ณ  ํ™˜๊ฒฝ์„ค์ •์—์„œ Enable Annotation Processing์„ ์ฒดํฌํ•ด์ฃผ์ž

์ด์ œ ํ”„๋กœ์ ํŠธ ํ™˜๊ฒฝ ์„ค์ •์— ๋Œ€ํ•ด์„œ๋Š” ๋ชจ๋“  ์ค€๋น„๊ฐ€ ๋๋‚ฌ๋‹ค.

 

Rest Api๋ฅผ ์ž‘์„ฑํ•˜๋Š” ์ผ๋งŒ ๋‚จ์•˜๋‹ค!


์ฝ”๋“œ ๊ตฌํ˜„

๋‹ค์Œ๊ณผ ๊ฐ™์ด DemoApplication์ด ์กด์žฌํ•˜๋Š” ๋””๋ ‰ํ† ๋ฆฌ์— 3๊ฐœ์˜ ํŒจํ‚ค์ง€๋ฅผ ๋งŒ๋“ค์–ด ์ฃผ์ž.

controller.package

์ปจํŠธ๋กค๋Ÿฌ๋ผ๊ณ  ํ•˜๋Š” ์„œ๋ฒ„์— ์—”ํŠธ๋ฆฌ ํฌ์ธํŠธ์™€ ์—”๋“œ ํฌ์ธํŠธ๋ฅผ ์ž‘์„ฑํ•  ํด๋ž˜์Šค์ด๋‹ค.


์ถ”ํ›„์— JPA๋ฅผ ๋” ๋ฐฐ์šฐ๊ณ  ์›น ์„œ๋ฒ„ ๊ตฌ์กฐ์— ๋Œ€ํ•ด์„œ ๋” ๊ณต๋ถ€ํ•˜๋ฉด ์•Œ๊ฒ ์ง€๋งŒ ํ•ด๋‹น ์„œ๋น„์Šค ๋กœ์ง์€ Service ํŒจํ‚ค์ง€์—์„œ ๊ด€๋ฆฌํ•œ ํด๋ž˜์Šค๋ฅผ Autowiredํ•˜์—ฌ ์„œ๋น„์Šค ๋กœ์ง์„ ์ž‘์„ฑํ•œ๋‹ค.


ํ•˜์ง€๋งŒ ์šฐ๋ฆฌ๋Š” ๊ฐ„๋‹จํ•œ CRUD ํ…Œ์ŠคํŠธ์ด๋ฏ€๋กœ ๋‹จ์ˆœํžˆ ์ปจํŠธ๋กค๋Ÿฌ๋งŒ ์ž‘์„ฑํ•ด๋ณด๋„๋ก ํ•˜์ž.

UserController.class ์ƒ์„ฑ

UserController๋กœ ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ์ž˜ ๋™์ž‘ํ•˜๋Š”์ง€ ํ…Œ์ŠคํŠธ๋ฅผ ํ•ด๋ณด์ž.

 

UserController๋ฅผ controller ํŒจํ‚ค์ง€ ํ•˜์œ„์— ์ƒ์„ฑํ•˜๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด์ž.

package com.example.demo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {
    @GetMapping("/get")
    public String getTest() {
        return "success";
    }
}
  • RestController

    ์ผ๋ฐ˜์ ์ธ Controller์™€๋Š” ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ•œ๋‹ค. ํ•ต์‹ฌ์€ ์šฐ๋ฆฌ๊ฐ€ Controller๋กœ ํŽ˜์ด์ง€๋ฅผ returnํ•˜๋Š”๊ฒŒ ์•„๋‹ˆ๋ผ Data(JSON)์„ returnํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ •ํ™•ํžˆ๋Š” ResponseBody๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ง€๋งŒ ํ˜„์žฌ ์‹œ์ ์—์„  ์‰ฝ๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ด๋„ ๋ฌด๋ฐฉํ•˜๋‹ค.

  • @GetMapping("")

    "" ์•ˆ์— ๋“ค์–ด๊ฐˆ URL๋กœ GET ์š”์ฒญ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์–ด๋…ธํ…Œ์ด์…˜์ด๋‹ค. ์ด ์–ด๋…ธํ…Œ์ด์…˜์€ @RequestMapping์— get ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•œ ๊ฒƒ๊ณผ ๊ฐ™์€ ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

๊ทธ๋ฆฌ๊ณ  localhost:8080/get ์ด๋ผ๋Š” ๊ฒฝ๋กœ๋ฅผ ์›น ๋ธŒ๋ผ์šฐ์ €๋ฅผ ํ†ตํ•ด์„œ ๋“ค์–ด๊ฐ€๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„ฑ๊ณต์ ์œผ๋กœ ๋™์ž‘ํ•œ ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

model.package

๋ฐ์ดํ„ฐ ๊ด€๋ จ Object๊ฐ€ ๋“ค์–ด๊ฐˆ ํŒจํ‚ค์ง€ ์ด๋‹ค.


์ด ๋ถ€๋ถ„๋„ ์ถ”ํ›„์— DAO, DTO, VO๋กœ ๋‚˜๋ˆ ์„œ ๊ด€๋ฆฌํ•˜๊ธฐ๋„ ํ•˜๊ณ  DAO, DTO๋กœ๋„ ๊ด€๋ฆฌํ•˜๊ธฐ๋„ ํ•œ๋‹ค.


์ผ๋‹จ์€ ์šฐ๋ฆฌ๋Š” ๋‹จ์ˆœ DAO ๊ฐ์ฒด๋งŒ ๋งŒ๋“ค์–ด๋ณด์ž.


์ž์„ธํ•œ ์‚ฌํ•ญ์€ ๊ตฌ๊ธ€๋ง์„ ํ†ตํ•ด ์•Œ์•„๋ณด๋Š” ๋ฐฉ๋ฒ•๋„ ์ข‹์€ ํ•™์Šต๋ฒ•์ด๋‹ค.

User.class ์ƒ์„ฑ

package com.example.demo.model;

import lombok.Data;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
@Data
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String username;

    private String password;
}

ํ•ด๋‹น ํด๋ž˜์Šค๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ์‹ค์ œ ๋งค์นญ๋˜๋Š” ์—ญํ• ์„ ํ•˜๋Š” ํด๋ž˜์Šค์ด๋‹ค.

  • @Entity

    ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ์—ฐ๊ฒฐ๋œ ๊ฐ์ฒด๋ฅผ Entity๋กœ ์ง€์ •ํ•œ๋‹ค๋Š” ์–ด๋…ธํ…Œ์ด์…˜์ด๋‹ค. ์šฐ๋ฆฌ๊ฐ€ Entity๋กœ ๋งŒ๋“ค์–ด์•ผ์ง€ Repository์—์„œ Entity๋ฅผ ๊ฐ€์ง€๊ณ  ์‰ฝ๊ฒŒ ์ฟผ๋ฆฌ๋ฌธ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค.

  • @Data

    ๋กฌ๋ณต์˜ ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ Getter๊ณผ Setter๋ฅผ ์ง์ ‘ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์•„๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ์–ด๋…ธํ…Œ์ด์…˜์ด๋‹ค.

  • @Id

    ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— Primary Key์— ํ•ด๋‹นํ•˜๋Š” ์นผ๋Ÿผ์„ ์ง€์ •ํ•˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜์ด๋‹ค. ๋งŒ์•ฝ ์šฐ๋ฆฌ๊ฐ€ ์•„์ด๋””๋ฅผ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋‚œ๋‹ค.

  • @GeneratedValue(strategy = GenerationType.IDENTITY)

    Id์˜ ์ŠคํŠธ๋ ˆํ„ฐ์ง€๋ฅผ ์ง€์ •ํ•˜๋Š” ๊ฒƒ์ธ๋ฐ ์‰ฝ๊ฒŒ ๋ง ํ•ด์„œ IDENETY๋ฅผ ์„ค์ •ํ•˜๋ฉด DB์˜ AutoIncreament๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

repository.package

JPA๊ฐ€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ฟผ๋ฆฌ๋ฌธ์„ ORM์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ํŒจํ‚ค์ง€์ด๋‹ค.


์šฐ๋ฆฌ๋Š” JpaRepository๋ผ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ตฌํ˜„ํ•  ๊ฒƒ์ด๋‹ค.

UserRepository.interface ์ƒ์„ฑ

package com.example.demo.repository;

import com.example.demo.model.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {

}
  • JpaRepository<Entity, Type>

    JpaRepository๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ์ง€์ •ํ•ด์ฃผ๋Š” ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ์ œ๋„ค๋ฆญ ํƒ€์ž… ์•ˆ์—๋Š” Entity ํด๋ž˜์Šค์™€ ํ•ด๋‹น ํด๋ž˜์Šค์˜ Id ํƒ€์ž…์ด ๋“ค์–ด๊ฐ„๋‹ค.

CRUD ํ…Œ์ŠคํŠธ

Controller ์ž‘์„ฑ

์ด์ œ ๋ชจ๋“  ์…‹์—…์ด ๋๋‚ฌ์œผ๋ฏ€๋กœ ๋‹ค์‹œ Controller๋กœ ๋Œ์•„๊ฐ€์„œ ์‹ค์ œ ํ†ต์‹ ์œผ๋กœ ์šฐ๋ฆฌ๊ฐ€ ์ž‘์„ฑํ•œ ์ฝ”๋“œ๊ฐ€ ์ž˜ ๋™์ž‘ํ•˜๋Š”์ง€ ํ™•์ธํ•ด๋ณด์ž.

package com.example.demo.controller;

import com.example.demo.model.User;
import com.example.demo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Optional;

@RestController
@RequestMapping("/api")
public class UserController {

    @Autowired
    private UserRepository userRepository;

    @PostMapping("/user")
    public User create(@RequestBody User user) {
        return userRepository.save(user);
    }

    @GetMapping("/user/{id}")
    public String read(@PathVariable Long id) {

        Optional<User> userOptional = userRepository.findById(id);
        userOptional.ifPresent(System.out::println);

        return "successfully executed";
    }
}

Api Tester๋กœ ํ…Œ์ŠคํŠธ

create ๋ฉ”์„œ๋“œ ์‹คํ–‰

create ๋ฉ”์„œ๋“œ๋Š” Controller์—์„œ ๋งคํ•‘ํ•˜๊ธธ localhost:8080/api/user ๋กœ ํ•˜์˜€์œผ๋ฏ€๋กœ ํ•ด๋‹น URL์— JSON ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋„˜๊ฒจ๋ณด์ž.


๊ฐ„๋‹จํ•˜๊ฒŒ ์—ฌ๊ธฐ์„œ ๋ง ํ•˜๋Š” JSON ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ์šฐ๋ฆฌ๊ฐ€ RequestBody๋กœ ๋ฐ›๋Š” User์˜ ๊ฐ์ฒด์ธ Key:value ํ˜•ํƒœ๋กœ ๊ฐ’์ด ๋„˜์–ด์˜ค๋Š” ๊ฒƒ์„ ๋œปํ•œ๋‹ค.


JSON์€ ์›น ๊ฐœ๋ฐœ์„ ํ•  ๋•Œ๋Š” ์ค‘์š”ํ•œ ๋‚ด์šฉ์ค‘ ํ•˜๋‚˜์ด๋ฏ€๋กœ ๊ผญ๊ผญ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ๋ผ๋„ ํ•™์Šต์„ ํ•ด๋ณด๊ธธ ๊ถŒ์žฅํ•œ๋‹ค.

์ •์ƒ์ ์œผ๋กœ ์ž˜ ์‹คํ–‰๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

read ๋ฉ”์„œ๋“œ ์‹คํ–‰

read๋ฉ”์„œ๋“œ๋Š” Controller์—์„œ ๋งคํ•‘์„ ํ•˜๊ธธ localhost:8080/api/user/{id}๋กœ ํ•˜์˜€์œผ๋ฏ€๋กœ ํ•ด๋‹น URL๋กœ ๋“ค์–ด๊ฐ€๋ณด์ž.

์ •์ƒ์ ์œผ๋กœ ์ž˜ ์‹คํ–‰๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 

 

์ด๋ ‡๊ฒŒ ์˜ค๋Š˜์€ IntelliJ์—์„œ ์Šคํ”„๋ง๋ถ€ํŠธ + ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค(Mysql) + ๋กฌ๋ณต์„ ์—ฐ๊ฒฐํ•˜์—ฌ ์›น ํ†ต์‹ ์— ๋Œ€ํ•ด ๊ฐ„์ ‘์ ์œผ๋กœ ์•Œ์•„๋ณด์•˜๋‹ค.

๊ธ€์˜ ์„ค๋ช…์—๋Š” Spring์˜ ์ง„์ž… ์žฅ๋ฒฝ์„ ๋‚ฎ์ถ”๊ธฐ ์œ„ํ•œ ๋งŽ์€ ๋น„์•ฝ์ด ์กด์žฌํ•˜๋Š”๋ฐ, ์–ด๋ ค์šด ๋‚ด์šฉ์€ ๊พธ์ค€ํžˆ ๊ตฌ๊ธ€๋ง์„ ํ†ตํ•ด ์ฑ„์›Œ๋‚˜๊ฐ€๋Š” ํ•™์Šต ๋ฐฉ๋ฒ•์„ ๊ถŒ์žฅํ•œ๋‹ค.

ํ™”์ดํŒ…!

๋Œ“๊ธ€