Backend/๐ŸŒฑ Spring

[Spring] Spring!

HS0601 2025. 7. 22. 15:41

 

@RestController
public class HelloController {

    @GetMapping("/hello")
    public String hello() {
        return "์•ˆ๋…• ์Šคํ”„๋ง!";
    }
}

 

 

 


 

 

Spring์„ ๋ฐฐ์šฐ๊ธฐ ์ด์ „์— ์•„์ฃผ ๊ทผ๋ณธ์ ์ธ ๊ถ๊ธˆ์ฆ๋ถ€ํ„ฐ ํ•ด๊ฒฐํ•ด ๋ณด๊ธฐ๋กœ ํ–ˆ๋‹ค.

[์‚ฌ์šฉ์ž (๋ธŒ๋ผ์šฐ์ €)]
    V ํด๋ฆญ
[React/Next.js] ——— ์š”์ฒญ(fetch/axios) ———โ–ถ [Spring ์„œ๋ฒ„]
                                            V
                                     [Service → DB]
                                           V
                               ์‘๋‹ต(JSON ํ˜•ํƒœ๋กœ ๋ณด๋‚ด์คŒ)

 

์ด์ œ๋ถ€ํ„ฐ๋Š” ํ”„๋ก ํŠธ์—์„œ API๋งŒ ์“ฐ๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ, ๊ทธ API ์ž์ฒด๋ฅผ ๋งŒ๋“œ๋Š” ์ชฝ
์ด๊ฒŒ ์Šคํ”„๋ง ๋ฐฑ์—”๋“œ์˜ ๋ณธ์งˆ.

 

Spring์ด๋ž€?

 

์ž๋ฐ”๋กœ ๋ฐฑ์—”๋“œ ์›น ์„œ๋น„์Šค๋ฅผ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ฃผ๋Š” ํ”„๋ ˆ์ž„์›Œํฌ!

 

Java๋ฐฑ์—”๋“œ=์„œ๋ฒ„๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ (์š”์ฒญ๋ฐ›๊ณ  ์ฒ˜๋ฆฌํ•˜๊ณ  ์‘๋‹ต๊นŒ์ง€)

๊ทธ๋Ÿฐ๋ฐ ์ž๋ฐ”๋กœ ์ง์ ‘ ๋‹ค ๋งŒ๋“ค๋ ค๋ฉด ๋„ˆ๋ฌด ๋ณต์žกํ•˜๊ณ  ํž˜์ด ๋“ ๋‹ค. ๐Ÿฅฒ 

๊ทธ๋ž˜์„œ Spring์ด๋ผ๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ๋“ฑ์žฅ..

 

Spring

๋ฐ˜๋ณต ์ž‘์—…์„ ์ค„์—ฌ์ฃผ๊ณ  ๊ธฐ๋ณธ ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“ค์–ด์ค˜์„œ ๊ฐœ๋ฐœ์ž๊ฐ€ ํ•ต์‹ฌ ๋กœ์ง์—๋งŒ ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๋น„๊ต) ํ”„๋ก ํŠธ ์ž…์žฅ์—์„œ ๋ณด๋ฉด, React๋Š” ํ™”๋ฉด(UI)์„ ๊ตฌ์„ฑํ•˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ, Spring์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ  ์‘๋‹ตํ•˜๋Š” ์„œ๋ฒ„ ์—ญํ• .

 

 

์Šคํ”„๋ง์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ

 

  • Controller : React์˜ ๋ผ์šฐํ„ฐ ๊ฐ™์ด URL์„ ๋งคํ•‘ํ•ด์ฃผ๋Š” ๊ณณ.

        → /users ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด ์–ด๋–ค ํ•จ์ˆ˜๊ฐ€ ์ฒ˜๋ฆฌํ• ์ง€ ์—ฐ๊ฒฐ

  • Service : ์ง„์งœ ์ค‘์š”ํ•œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง (๊ณ„์‚ฐ, ์กฐ๊ฑด์ฒ˜๋ฆฌ ๋“ฑ)
  • Repository : DB๋ž‘ ์—ฐ๊ฒฐํ•ด์ฃผ๋Š” ์—ญํ• (๋ฐ์ดํ„ฐ ์ €์žฅ/์กฐํšŒ)
  • Model/ Entity : DBํ…Œ์ด๋ธ”์ฒ˜๋Ÿผ ์ƒ๊ธด ์ž๋ฐ” ํด๋ž˜์Šค (User, Produce ๋“ฑ)
  • DI (์˜์กด์„ฑ ์ฃผ์ž…) : ํ•„์š”ํ•œ ๊ฐ์ฒด๋ฅผ ์ž๋™์œผ๋กœ ์—ฐ๊ฒฐํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ (React์—์„œ props, context, useEffect์ฒ˜๋Ÿผ ๋ญ”๊ฐ€ ์—ฐ๊ฒฐํ•ด์ฃผ๋Š” ๋А๋‚Œ)

 

์Šคํ”„๋ง ๋ถ€ํŠธ???

์Šคํ”„๋ง์„ ๋” ์‰ฝ๊ฒŒ ๋น ๋ฅด๊ฒŒ ์“ธ ์ˆ˜ ์žˆ๋Œ๊ณ  ๋งŒ๋“ค์–ด์ง„ ํˆดํ‚ท

 

์Šคํ”„๋ง ์„ค์ •์ด ๋„ˆ๋ฌด ๋ณต์žกํ•ด์„œ Spring Boot๊ฐ€ ๋“ฑ์žฅ

React์—์„œ CRA(Create React App)์ฒ˜๋Ÿผ ํ”„๋กœ์ ํŠธ ๋ผˆ๋Œ€๋ฅผ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๋А๋‚Œ

๋‚ด์žฅ Tomcat ์„œ๋ฒ„ ๋•๋ถ„์— main()๋งŒ ์‹คํ–‰ํ•˜๋ฉด ๋ฐ”๋กœ ์„œ๋ฒ„๊ฐ€ ๋™์ž‘ํ•จ

 

์‰ฝ๊ฒŒ ๋งํ•ด  ์Šคํ”„๋ง ๋ถ€ํŠธ๋Š” "์Šคํ”„๋ง์˜ ๊ท€์ฐฎ์€ ์„ค์ •์„ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•ด์ฃผ๋Š” ๋„์šฐ๋ฏธ"

์Šคํ”„๋ง(Spring) ์Šคํ”„๋ง ๋ถ€ํŠธ(Spring Boot)

 

  ์Šคํ”„๋ง(Spring) ์Šคํ”„๋ง ๋ถ€ํŠธ(Spring Boot)
์ •์˜ ๋ฐฑ์—”๋“œ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํ”„๋ ˆ์ž„์›Œํฌ ์Šคํ”„๋ง์„ ์‰ฝ๊ฒŒ ์“ธ ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ฃผ๋Š” ํˆดํ‚ท
ํŠน์ง• ์„ค์ •์ด ๋„ˆ๋ฌด ๋ณต์žกํ•จ(XML, ์ˆ˜๋™์„ค์ • ๋“ฑ) ์„ค์ •์„ ์ž๋™์œผ๋กœ ํ•ด์คŒ!(์ž๋™ ์„ค์ •, ๋‚ด์žฅ ์„œ๋ฒ„ ๋“ฑ)
์‹คํ–‰ ๋ฐฉ์‹ ๋”ฐ๋กœ ์„œ๋ฒ„ ํ•„์š” (Tomcat ์„ค์น˜) ์‹คํ–‰๋งŒ ํ•˜๋ฉด ์„œ๋ฒ„๊ฐ€ ๋ฐ”๋กœ ๋œธ (main() ๋ˆ„๋ฅด๋ฉด ๋)
๊ฐœ๋ฐœ ์†๋„ ๋А๋ฆผ (์ดˆ๊ธฐ ์„ธํŒ… ๊ท€์ฐฎ์Œ) ๋น ๋ฆ„ (๊ฐœ๋ฐœ์ž ํ–‰๋ณต๋„ ์ƒ์Šน)

 

๊ตฌ๋ถ„ React/Next (ํ”„๋ก ํŠธ) Spring (๋ฐฑ์—”๋“œ)
  React/Next (ํ”„๋ก ํŠธ) Spring (๋ฐฑ์—”๋“œ)
๊ตฌ์„ฑ ์ปดํฌ๋„ŒํŠธ ์ค‘์‹ฌ ๊ณ„์ธต ๊ตฌ์กฐ (Controller → Service → Repository)
๋ผ์šฐํŒ… react-router @GetMapping("/url")
์ƒํƒœ๊ด€๋ฆฌ useState, Redux ์„œ๋น„์Šค/DB ๋‚ด๋ถ€ ์ฒ˜๋ฆฌ
๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ fetch, axios ๋‚ด๋ถ€์—์„œ @Async or ๋™๊ธฐ ๊ธฐ๋ณธ
์‹œ์ž‘ npm start main() ์‹คํ–‰ ๋˜๋Š” ./gradlew bootRun

 

๊ฐ„๋‹จ์ •๋ฆฌ 
1 ์Šคํ”„๋ง ๋ถ€ํŠธ ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ๋ฒ• CRA์ฒ˜๋Ÿผ ์Šคํ”„๋ง ๋ถ€ํŠธ ํ”„๋กœ์ ํŠธ ๋ผˆ๋Œ€ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•
2 Controller ๊ฐœ๋… + @GetMapping, @PostMapping URL → ํ•จ์ˆ˜ ์—ฐ๊ฒฐ. ๋ผ์šฐํŒ…. react-router-dom ๋А๋‚Œ
3 ์š”์ฒญ ๋ฐ›๊ธฐ: @RequestParam, @PathVariable, @RequestBody ์‚ฌ์šฉ์ž ์ž…๋ ฅ๊ฐ’์„ ์„œ๋ฒ„์—์„œ ๋ฐ›๋Š” ๋ฒ• (ํผ, fetch ๋“ฑ๊ณผ ์—ฐ๋™)
4 ์‘๋‹ต ๋ณด๋‚ด๊ธฐ: JSON ์‘๋‹ต React๋กœ fetch ํ–ˆ์„ ๋•Œ JSON์œผ๋กœ ์‘๋‹ต ์ฃผ๋Š” ๋ฐฉ๋ฒ•
5 DTO๋ž€? ์š”์ฒญ, ์‘๋‹ต ๋ฐ์ดํ„ฐ ๊ตฌ์กฐํ™” ํด๋ž˜์Šค (props ๋А๋‚Œ)
6 Service ๊ฐœ๋… ๋กœ์ง ์ฒ˜๋ฆฌํ•˜๋Š” ๋ ˆ์ด์–ด. ๊ณ„์‚ฐ, ์กฐ๊ฑด, ๋กœ์ง ๋“ฑ ์ˆ˜ํ–‰
7 Repository + DB ์—ฐ๊ฒฐ ์‹ค์ œ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ฑฐ๋‚˜ ๋ถˆ๋Ÿฌ์˜ด (JPA, H2๋ถ€ํ„ฐ ์‹œ์ž‘)
8 ์˜์กด์„ฑ ์ฃผ์ž…(DI) Spring์ด ์ž๋™์œผ๋กœ ๊ฐ์ฒด ๋„ฃ์–ด์ฃผ๋Š” ๊ธฐ๋Šฅ (์ƒ์„ฑ์ž ๊ธฐ๋ฐ˜์œผ๋กœ ์ฃผ์ž…)
9 application.properties ์„ค์ • ํ”„๋กœ์ ํŠธ ์„ค์ •ํŒŒ์ผ. ํฌํŠธ, DB ์—ฐ๊ฒฐ, ๋กœ๊ทธ ์„ค์ • ๋“ฑ
10 (๋ณด๋„ˆ์Šค) Postman, Swagger API ํ…Œ์ŠคํŠธ ํˆด. ํ”„๋ก ํŠธ ์—†์ด๋„ API ํ…Œ์ŠคํŠธ ๊ฐ€๋Šฅ!

์งˆ๋ฌธ ์ •๋ฆฌ

 

Q1. @GetMapping("/url") ์ด๊ฑฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ธ๊ฐ€? (npm install react-router-dom ๊ฐ™์€)

No. ์ด๊ฑด ์ž๋ฐ”์˜ "์–ด๋…ธํ…Œ์ด์…˜"์ด๋ผ๋Š” ๋ฌธ๋ฒ•์ด๊ณ , ์ปดํŒŒ์ผ ์‹œ ์ž๋™์œผ๋กœ ์ž‘๋™๋˜๋Š” ์„ค์ •

@GetMapping("/url")๋Š” Spring Web์ด๋ผ๋Š” ์Šคํ”„๋ง ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์ผ๋ถ€ ๊ธฐ๋Šฅ

์ด๊ฑธ ์“ฐ๊ธฐ ์œ„ํ•ด์„  ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ ์‹œ spring-boot-starter-web์„ ํฌํ•จํ•ด์•ผ ํ•จ

 

React์—์„œ๋Š” npm install react-router-dom์œผ๋กœ ๋ผ์šฐํŒ… ์„ค์ •ํ–ˆ๋Š”๋ฐ, 

์Šคํ”„๋ง์—์„œ๋Š” @GetMapping, @PostMapping์œผ๋กœ URL์— ๋”ฐ๋ผ ๋ฉ”์„œ๋“œ๋ฅผ ๋งตํ•‘ํ•ด์ฃผ๋Š” ๋ฐฉ์‹์ž„.

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello() {
        return "Hello from Spring!";
    }
}
///hello๋กœ ์š”์ฒญํ•˜๋ฉด ์ € ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋จ → ๋ฐ˜ํ™˜๊ฐ’ "Hello from Spring!"์ด ๋ธŒ๋ผ์šฐ์ €์— ์ถœ๋ ฅ๋จ

 

Q2. ์ž๋ฐ”์„ธ์ƒ์—๋Š” ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €๊ฐ€ ์—†๋Š”๊ฐ€?

No. ์ž๋ฐ” ์ชฝ์—์„œ๋Š” Maven์ด๋‚˜ Gradle์ด๋ผ๋Š” ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €๊ฐ€ ์กด์žฌํ•จ.

 

ํ”„๋ก ํŠธ (JS) ๋ฐฑ์—”๋“œ (Java)

npm, yarn Gradle, Maven
npm start ./gradlew bootRun ๋˜๋Š” main() ์‹คํ–‰

 

  • package.json → build.gradle
  • npm install → ./gradlew build (๋˜๋Š” IntelliJ๊ฐ€ ์ž๋™ ๊ด€๋ฆฌ)

๋˜๋Š” IntelliJ์—์„œ main() ์šฐํด๋ฆญ → Run ํ•˜๋ฉด ๋ฐ”๋กœ ์‹คํ–‰๋จ
→ localhost:8080์œผ๋กœ ์„œ๋ฒ„๊ฐ€ ๋œธ (React์ฒ˜๋Ÿผ 3000 ์•„๋‹ˆ๊ณ )

 

Q3. fetch/axios๋Š” ์™ธ๋ถ€ API ์š”์ฒญ์ธ๋ฐ, ์Šคํ”„๋ง์€ ์ž์ฒด๊ฐ€ API ๋งŒ๋“œ๋Š” ๊ฑฐ ์•„๋‹Œ๊ฐ€??

Yes. ์ •๋ง ๋‚ ์นด๋กœ์šด ์งˆ๋ฌธ

  • React์—์„œ๋Š” ์™ธ๋ถ€ API ํ˜ธ์ถœ(fetch/axios)
  • Spring์€ API๋ฅผ ์ง์ ‘ ๋งŒ๋“œ๋Š” ์ชฝ (์„œ๋ฒ„ ์—ญํ• )

์Šคํ”„๋ง๋„ ๋‹ค๋ฅธ ์™ธ๋ถ€ ์„œ๋ฒ„์— ์š”์ฒญํ•˜๊ณ  ์‹ถ์„ ๋•Œ๊ฐ€ ์žˆ์Œ.
→ ์ด๋Ÿด ๋• ์ž๋ฐ”์—์„œ๋Š” RestTemplate, WebClient๋ฅผ ์‚ฌ์šฉํ•ด fetch/axios์™€ ์œ ์‚ฌํ•œ ์—ญํ• 

@RestController
public class ExternalApiController {

    @GetMapping("/external")
    public String callOtherApi() {
        RestTemplate rt = new RestTemplate();
        String response = rt.getForObject("https://api.example.com/data", String.class);
        return response;
    }
}

 

@Async๋Š” ๋ญ๋ƒ๋ฉด, ๋‚ด๋ถ€์—์„œ ๋น„๋™๊ธฐ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์“ฐ๋Š” ๊ฑฐ์ž„

 

@Async
public void backgroundJob() {
    // ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋Š” ์ž‘์—…
}

 

 

Q4. ์„œ๋น„์Šค/DB ๋‚ด๋ถ€ ์ฒ˜๋ฆฌ?? 

useState๋Š” ํด๋ผ์ด์–ธํŠธ(๋ธŒ๋ผ์šฐ์ €)์—์„œ ๋ฐ์ดํ„ฐ ์ €์žฅ์ด์ง€๋งŒ
์Šคํ”„๋ง์˜ Service/Repository๋Š” ์„œ๋ฒ„ ๋‚ด์—์„œ ๋กœ์ง ์ฒ˜๋ฆฌ + DB ์ €์žฅ

์˜ˆ์‹œ: ์‚ฌ์šฉ์ž๊ฐ€ ์ด๋ฆ„์„ ์ž…๋ ฅํ•˜๋ฉด → ์„œ๋ฒ„์—์„œ DB์— ์ €์žฅ → ๋‹ค์‹œ ๋ชฉ๋ก ๋ณด์—ฌ์คŒ

 

์˜ˆ์‹œ ์ฝ”๋“œ (์Šคํ”„๋ง ๊ตฌ์กฐ)

 

  • useState๋Š” ๋ธŒ๋ผ์šฐ์ € ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ
  • Spring์€ ์‹ค์ œ DB์— ์ €์žฅํ•˜๊ณ ์š”์ฒญ๋ฐ›์•„์„œ ์‘๋‹ต๊นŒ์ง€ ํ•จ

 

// 1. Entity (DB ํ…Œ์ด๋ธ”์ฒ˜๋Ÿผ ์ƒ๊น€)
@Entity
public class User {
    @Id @GeneratedValue
    private Long id;
    private String name;
}

// 2. Repository (DB ์ €์žฅ์†Œ)
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}

// 3. Service (๋กœ์ง ์ฒ˜๋ฆฌ)
@Service
public class UserService {
    private final UserRepository repo;

    public UserService(UserRepository repo) {
        this.repo = repo;
    }

    public void saveUser(String name) {
        User user = new User();
        user.setName(name);
        repo.save(user); // DB์— ์ €์žฅ
    }

    public List<User> findAllUsers() {
        return repo.findAll(); // ์ „์ฒด ๋ชฉ๋ก ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
    }
}

// 4. Controller (API ๋…ธ์ถœ)
@RestController
public class UserController {
    private final UserService service;

    public UserController(UserService service) {
        this.service = service;
    }

    @PostMapping("/user")
    public void createUser(@RequestParam String name) {
        service.saveUser(name);
    }

    @GetMapping("/user")
    public List<User> getUsers() {
        return service.findAllUsers();
    }
}

 

 

 

 

 

'Backend > ๐ŸŒฑ Spring' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[Spring]์˜์กด๊ด€๊ณ„ ์ฃผ์ž…(DI)  (2) 2025.07.28
[Spring]Spring Bean  (2) 2025.07.28
[Spring] Layered Architecture  (3) 2025.07.26
[Spring] Mapping  (1) 2025.07.23
[Spring]MVC  (4) 2025.07.23