๐Ÿ“š spring_ssr ํ”„๋กœ์ ํŠธ ์ „์ฒด ์ •๋ฆฌ

Spring Boot 3.3 + Thymeleaf SSR ๋ฐฉ์‹์˜ ์ปค๋ฎค๋‹ˆํ‹ฐ ๊ฒŒ์‹œํŒ ํ”„๋กœ์ ํŠธ
MVC ํŒจํ„ด ๊ธฐ๋ณธ๊ธฐ + IoC/DI, AOP ๊ฐœ๋… ํ•™์Šต + ๊ฒŒ์‹œ๊ธ€ยท๋Œ“๊ธ€ยทํŒŒ์ผ ๊ธฐ๋Šฅ ๊ตฌํ˜„


๐Ÿ“ ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ ๊ฐœ์š”

spring_ssr/
โ”œโ”€โ”€ ์„ค๊ณ„/                         โ† md ๊ฐ•์˜ ๋ฌธ์„œ
โ”œโ”€โ”€ src/main/java/com/
โ”‚   โ”œโ”€โ”€ ch/basic/                 โ† ์‹ค์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ (com.ch.basic)
โ”‚   โ”‚   โ”œโ”€โ”€ DemoApplication.java
โ”‚   โ”‚   โ”œโ”€โ”€ HomeController.java
โ”‚   โ”‚   โ”œโ”€โ”€ community/            โ† ๊ฒŒ์‹œ๊ธ€ (SSR)
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ comment/          โ† ๋Œ“๊ธ€ (REST API)
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ dto/
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ repository/
โ”‚   โ”‚   โ”œโ”€โ”€ user/                 โ† ํšŒ์› (์„ธ์…˜ ๋กœ๊ทธ์ธ)
โ”‚   โ”‚   โ”œโ”€โ”€ file/                 โ† ํŒŒ์ผ (์ฒจ๋ถ€ํŒŒ์ผ + ์—๋””ํ„ฐ ์ด๋ฏธ์ง€)
โ”‚   โ”‚   โ”œโ”€โ”€ api/                  โ† ๊ณต๊ณต๋ฐ์ดํ„ฐ API ํ”„๋ก์‹œ
โ”‚   โ”‚   โ””โ”€โ”€ common/               โ† ๊ณตํ†ต (config, exception, scheduler, dto)
โ”‚   โ”œโ”€โ”€ ioc/step1~4/              โ† IoC/DI ๊ฐœ๋… ํ•™์Šต์šฉ ์ฝ”๋“œ
โ”‚   โ””โ”€โ”€ aop/step1~4/              โ† AOP ๊ฐœ๋… ํ•™์Šต์šฉ ์ฝ”๋“œ
โ”œโ”€โ”€ src/main/resources/
โ”‚   โ”œโ”€โ”€ application.yml
โ”‚   โ”œโ”€โ”€ data-*.sql                โ† ์ดˆ๊ธฐ ๋ฐ์ดํ„ฐ
โ”‚   โ””โ”€โ”€ templates/                โ† Thymeleaf ํ…œํ”Œ๋ฆฟ
โ””โ”€โ”€ build.gradle

๊ธฐ์ˆ  ์Šคํƒ

ํ•ญ๋ชฉ ๊ธฐ์ˆ 
Framework Spring Boot 3.3.4, Java 17
View Thymeleaf (SSR)
ORM Spring Data JPA + QueryDSL 5.0
DB MariaDB
๋นŒ๋“œ Gradle
๊ธฐํƒ€ Lombok, spring-dotenv, Validation, AOP, DevTools

๐Ÿ“– ์„ค๊ณ„ ๋ฌธ์„œ (md) โ†” ์‹ค์ œ ์ฝ”๋“œ ๋งค์นญ ๊ฒ€์ฆ

โœ… ์ผ์น˜ํ•˜๋Š” ํ•ญ๋ชฉ

md ๋ฌธ์„œ ์‹ค์ œ ์ฝ”๋“œ ์ƒํƒœ
๊ฐœ๋…_01_IoC_DI.md โ€” step1~4 ํ•™์Šต ํ๋ฆ„ com.ioc.step1~4 ํŒจํ‚ค์ง€ ์กด์žฌ, ๊ฐ step๋ณ„ Main.java ์žˆ์Œ โœ… ์ผ์น˜
๊ฐœ๋…_02_MVCํŒจํ„ด.md โ€” SSR ํ๋ฆ„, Controller/Model/View CommunityController, UserController, templates/ โœ… ์ผ์น˜
๊ฐœ๋…_06_Transaction.md โ€” readOnly + @Transactional ํŒจํ„ด CommunityService, CommentService, FileService ๋ชจ๋‘ ์ด ํŒจํ„ด ์ ์šฉ โœ… ์ผ์น˜
๊ฐœ๋…_07_Session_Login.md โ€” HttpSession ๋กœ๊ทธ์ธ UserController.login(), LoginUserDTO ์„ธ์…˜ ์ €์žฅ โœ… ์ผ์น˜
๊ฐœ๋…_08_Validation.md โ€” @Valid ์„ค๋ช… build.gradle์— spring-boot-starter-validation ์žˆ์Œ โœ… ์ผ์น˜
๊ฐœ๋…_09_Exception.md โ€” ์ปค์Šคํ…€ ์˜ˆ์™ธ ๊ณ„์ธต BusinessException โ†’ EntityNotFoundException/AccessDeniedException/BusinessRuleException/DuplicateResourceException ์กด์žฌ โœ… ์ผ์น˜
๊ฐœ๋…_09_Exception.md โ€” GlobalExceptionHandler vs ApiExceptionHandler GlobalExceptionHandler(@ControllerAdvice) + ApiExceptionHandler(@RestControllerAdvice) ๋ถ„๋ฆฌ ์ ์šฉ โœ… ์ผ์น˜
๊ฐœ๋…_10_AOP.md โ€” step1~4 ํ•™์Šต ํ๋ฆ„ com.aop.step1~4 ํŒจํ‚ค์ง€ ์กด์žฌ, ๊ฐ step๋ณ„ ํŒŒ์ผ ๊ตฌ์กฐ ์ผ์น˜ โœ… ์ผ์น˜
๊ฐœ๋…_11_Filter_Interceptor.md โ€” Interceptor ์ ์šฉ LoginCheckInterceptor + WebConfig ์ฝ”๋“œ์™€ md ์„ค๋ช… ์ผ์น˜ โœ… ์ผ์น˜
ํ”„๋กœ์ ํŠธ_๊ตฌ์กฐ_์ •๋ฆฌ.md โ€” ๋Œ“๊ธ€ REST API CommentApiController ๊ฒฝ๋กœ/๋ฉ”์„œ๋“œ/์‘๋‹ต ์ผ์น˜ โœ… ์ผ์น˜
ํ”„๋กœ์ ํŠธ_๊ตฌ์กฐ_์ •๋ฆฌ.md โ€” ํŒŒ์ผ ์ฒ˜๋ฆฌ ํ๋ฆ„ FileService, FileController, FileApiController ๋™์ž‘ ์ผ์น˜ โœ… ์ผ์น˜
ํ”„๋กœ์ ํŠธ_๊ตฌ์กฐ_์ •๋ฆฌ.md โ€” ์Šค์ผ€์ค„๋Ÿฌ ๊ณ ์•„ ํŒŒ์ผ ์‚ญ์ œ FileCleanupScheduler (๋งค์ผ ์ƒˆ๋ฒฝ 4์‹œ, refId=0 + 24์‹œ๊ฐ„) ์ผ์น˜ โœ… ์ผ์น˜
ํ”„๋กœ์ ํŠธ_๊ตฌ์กฐ_์ •๋ฆฌ.md โ€” ์†Œํ”„ํŠธ/ํ•˜๋“œ ์‚ญ์ œ ์ •์ฑ… User(์†Œํ”„ํŠธ, @SQLRestriction), Community/Comment(ํ•˜๋“œ), File(๊ณ ์•„โ†’์Šค์ผ€์ค„๋Ÿฌ) ์ผ์น˜ โœ… ์ผ์น˜
ํ”„๋กœ์ ํŠธ_๊ตฌ์กฐ_์ •๋ฆฌ.md โ€” ๊ฒŒ์‹œ๊ธ€ ์‚ญ์ œ ํ๋ฆ„ CommunityController.delete(): ํŒŒ์ผ๊ณ ์•„โ†’๋Œ“๊ธ€์‚ญ์ œโ†’๊ฒŒ์‹œ๊ธ€์‚ญ์ œ ์ˆœ์„œ ์ผ์น˜ โœ… ์ผ์น˜

โš ๏ธ md ๋ฌธ์„œ ๋ถˆ์ผ์น˜ ์‚ฌํ•ญ โ€” ์ˆ˜์ • ์™„๋ฃŒ

์•„๋ž˜ ํ•ญ๋ชฉ๋“ค์€ ๋ชจ๋‘ ์ˆ˜์ • ์™„๋ฃŒ๋จ.

# ํŒŒ์ผ ์ˆ˜์ • ๋‚ด์šฉ
1 ๊ฐœ๋…_00_๋ชฉ์ฐจ.md ์กด์žฌํ•˜์ง€ ์•Š๋Š” 04_JPA_Repository, 05_QueryDSL, 12_Security ์ œ๊ฑฐ. ์‹ค์ œ 12_์Šค์ผ€์ฅด๋Ÿฌ ์ถ”๊ฐ€. ์ฐธ๊ณ  ๋ฌธ์„œ(์„œ๋น„์Šค์„ค๊ณ„, ํŒŒ์ผํ…Œ์ด๋ธ”์„ค๊ณ„ ๋“ฑ) ์„น์…˜ ์ถ”๊ฐ€
2 ๊ฐœ๋…_07_Session_Login.md UserEntity โ†’ LoginUserDTO๋กœ ์ˆ˜์ • (Entity๋ฅผ ์„ธ์…˜์— ์ €์žฅํ•˜์ง€ ์•Š๋Š” ์ด์œ  ์„ค๋ช… ์ถ”๊ฐ€)
3 ๊ฐœ๋…_08_Validation.md ํ˜„์žฌ ์ฝ”๋“œ๋Š” @RequestParam ๋ฐฉ์‹์ด์ง€๋งŒ, ๋ฌธ์„œ๋Š” @Valid ์ •์„ ์‚ฌ์šฉ๋ฒ• ์ •๋ฆฌ ๋ชฉ์ ์ž„์„ ์•ˆ๋‚ด ์ถ”๊ฐ€
4 ๊ฐœ๋…_01_IoC_DI.md ํŒจํ‚ค์ง€ com.test.test โ†’ com.ch.basic
5 ๊ฐœ๋…_10_AOP.md ํŒจํ‚ค์ง€ com.test.test โ†’ com.ch.basic (10๊ฑด ์ „์ฒด ์น˜ํ™˜)
6 ๊ฐœ๋…_09_Exception.md @ControllerAdvice โ†’ @ControllerAdvice(annotations = Controller.class), @RestControllerAdvice โ†’ @RestControllerAdvice(annotations = RestController.class), findByIdAndIsDeletedFalse โ†’ findById, @Slf4j ์ œ๊ฑฐ

๐Ÿ“Œ ๋‚จ์•„์žˆ๋Š” ๋ฏธ์ž‘์„ฑ ํ•ญ๋ชฉ

๋ชจ๋“  ๊ฐœ๋… ๋ฌธ์„œ ์ž‘์„ฑ ์™„๋ฃŒ.


๐Ÿ”ง ์‹ค์ œ ๊ตฌํ˜„๋œ ๊ธฐ๋Šฅ ์ •๋ฆฌ

1. ๊ฒŒ์‹œ๊ธ€ (SSR โ€” @Controller)

๊ธฐ๋Šฅ URL HTTP ์ฒ˜๋ฆฌ
๋ชฉ๋ก (๊ฒ€์ƒ‰+ํŽ˜์ด์ง•) /community GET QueryDSL ๋™์  ์ฟผ๋ฆฌ, PageResponse
์ž‘์„ฑ ํผ /community/write GET ๋กœ๊ทธ์ธ ํ•„์ˆ˜ (Interceptor)
์ž‘์„ฑ ์ฒ˜๋ฆฌ /community/write POST ๊ธ€ ๋“ฑ๋ก โ†’ ์—๋””ํ„ฐ์ด๋ฏธ์ง€ ์—ฐ๊ฒฐ โ†’ ์ฒจ๋ถ€ํŒŒ์ผ ์ €์žฅ โ†’ redirect
์ƒ์„ธ /community/{id} GET ์กฐํšŒ์ˆ˜ ์ฆ๊ฐ€, ๋Œ“๊ธ€ยทํŒŒ์ผ์€ JS์—์„œ API ํ˜ธ์ถœ
์ˆ˜์ • ํผ /community/{id}/edit GET ๋กœ๊ทธ์ธ ํ•„์ˆ˜
์ˆ˜์ • ์ฒ˜๋ฆฌ /community/{id}/edit POST ๊ธ€ ์ˆ˜์ • โ†’ ์—๋””ํ„ฐ์ด๋ฏธ์ง€ ๋™๊ธฐํ™” โ†’ ํŒŒ์ผ์‚ญ์ œ โ†’ ์ƒˆํŒŒ์ผ์ €์žฅ
์‚ญ์ œ /community/{id}/delete POST ํŒŒ์ผ๊ณ ์•„์ฒ˜๋ฆฌ โ†’ ๋Œ“๊ธ€์‚ญ์ œ โ†’ ๊ฒŒ์‹œ๊ธ€์‚ญ์ œ

2. ๋Œ“๊ธ€ (REST API โ€” @RestController)

๊ธฐ๋Šฅ URL HTTP ์‘๋‹ต
๋ชฉ๋ก GET /api/communities/{id}/comments?page=0&size=10 GET JSON (PageResponse)
์ž‘์„ฑ POST /api/communities/{id}/comments POST JSON (201 Created)
์ˆ˜์ • PUT /api/communities/{id}/comments/{commentId} PUT JSON
์‚ญ์ œ DELETE /api/communities/{id}/comments/{commentId} DELETE JSON

3. ํŒŒ์ผ

๊ธฐ๋Šฅ Controller URL ์šฉ๋„
๋‹ค์šด๋กœ๋“œ FileController (@Controller) GET /files/download/{fileId} ์ฒจ๋ถ€ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ
์ด๋ฏธ์ง€ ์„œ๋น™ FileController (@Controller) GET /uploads/{filename} ์—๋””ํ„ฐ ๋ณธ๋ฌธ ์ด๋ฏธ์ง€
๋ชฉ๋ก ์กฐํšŒ FileApiController (@RestController) GET /api/files?refId=&refType=&usage= JS fetch
์—…๋กœ๋“œ FileApiController (@RestController) POST /api/files/upload ์—๋””ํ„ฐ ์ด๋ฏธ์ง€ ์ฆ‰์‹œ ์—…๋กœ๋“œ

4. ํšŒ์›

๊ธฐ๋Šฅ URL HTTP
๋กœ๊ทธ์ธ ํผ /login GET
๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌ /login POST
๋กœ๊ทธ์•„์›ƒ /logout POST
ํšŒ์›๊ฐ€์ž… ํผ /signup GET
ํšŒ์›๊ฐ€์ž… ์ฒ˜๋ฆฌ /signup POST
๋งˆ์ดํŽ˜์ด์ง€ /mypage GET

5. ๊ณต๊ณต๋ฐ์ดํ„ฐ API ํ”„๋ก์‹œ

๊ธฐ๋Šฅ URL
API ํ…Œ์ŠคํŠธ ํŽ˜์ด์ง€ GET /api/test โ†’ templates/api.html
์‹œ๊ตฐ๊ตฌ๋ณ„ ๊ด€๊ด‘๊ธฐํ›„์ง€์ˆ˜ GET /api/proxy/city-climate
๋™๋„ค์˜ˆ๋ณด GET /api/proxy/tour-forecast

6. ๊ฐœ๋… ํ•™์Šต์šฉ ์ฝ”๋“œ (standalone)

ํŒจํ‚ค์ง€ ๋‚ด์šฉ
com.ioc.step1 ์ง์ ‘ ๊ฐ์ฒด ์ƒ์„ฑ โ†’ ๊ฐ•ํ•œ ๊ฒฐํ•ฉ
com.ioc.step2 ์ธํ„ฐํŽ˜์ด์Šค + ์ƒ์„ฑ์ž ์ฃผ์ž… โ†’ IoC ์‹œ์ž‘
com.ioc.step3 Assembler ๋„์ž… โ†’ IoC ์ปจํ…Œ์ด๋„ˆ ์›ํ˜•
com.ioc.step4 Spring ์ปจํ…Œ์ด๋„ˆ (@Configuration + @Bean)
com.aop.step1 AOP ์—†์ด โ€” ๋ถ€๊ฐ€ ๋กœ์ง ์ค‘๋ณต
com.aop.step2 ํ”„๋ก์‹œ ํŒจํ„ด โ€” ์ˆ˜๋™ ๋ถ„๋ฆฌ
com.aop.step3 JDK Dynamic Proxy โ€” ์ž๋™ ํ”„๋ก์‹œ
com.aop.step4 Spring AOP โ€” @Aspect + Pointcut

๐Ÿ“Š ์•„ํ‚คํ…์ฒ˜ ์š”์•ฝ

[๋ธŒ๋ผ์šฐ์ €]
   โ”‚
   โ”œโ”€ SSR ์š”์ฒญ (GET/POST form) โ”€โ”€โ†’ [LoginCheckInterceptor] โ”€โ”€โ†’ [@Controller]
   โ”‚                                                              โ”‚
   โ”‚                                                    CommunityController
   โ”‚                                                    UserController
   โ”‚                                                    FileController
   โ”‚                                                              โ”‚
   โ”‚                                                      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”
   โ”‚                                                  [Service]    [Service]
   โ”‚                                                      โ”‚            โ”‚
   โ”‚                                              [Repository]  [Repository]
   โ”‚                                              (JPA+QueryDSL)
   โ”‚
   โ”œโ”€ REST API (JS fetch) โ”€โ”€โ†’ [@RestController]
   โ”‚                           CommentApiController  (์ž์ฒด ์„ธ์…˜ ์ฒดํฌ โ†’ 401 JSON)
   โ”‚                           FileApiController
   โ”‚                           ApiProxyController    (๊ณต๊ณตAPI ํ”„๋ก์‹œ)
   โ”‚
   โ”‚  ์˜ˆ์™ธ ๋ฐœ์ƒ ์‹œ:
   โ”‚   @Controller  โ†’ GlobalExceptionHandler  โ†’ error.html
   โ”‚   @RestController โ†’ ApiExceptionHandler  โ†’ JSON ErrorResponse
   โ”‚
   โ””โ”€ ์Šค์ผ€์ค„๋Ÿฌ
       FileCleanupScheduler (๋งค์ผ 04:00 โ€” ๊ณ ์•„ ํŒŒ์ผ ๋ฌผ๋ฆฌ์‚ญ์ œ + DB์‚ญ์ œ)

โœ… ์ˆ˜์ • ์™„๋ฃŒ ์š”์•ฝ

# ์œ„์น˜ ์ˆ˜์ • ๋‚ด์šฉ ์ƒํƒœ
1 ๊ฐœ๋…_00_๋ชฉ์ฐจ.md 04_JPA_Repository, 05_QueryDSL, 12_Security ์ œ๊ฑฐ, 12_์Šค์ผ€์ฅด๋Ÿฌ ๋ฐ ์ฐธ๊ณ  ๋ฌธ์„œ ์ถ”๊ฐ€ โœ… ์™„๋ฃŒ
2 ๊ฐœ๋…_07_Session_Login.md UserEntity โ†’ LoginUserDTO๋กœ ์ „์ฒด ์ˆ˜์ • โœ… ์™„๋ฃŒ
3 ๊ฐœ๋…_08_Validation.md ํ˜„์žฌ ์ฝ”๋“œ๋Š” @RequestParam, ๋ฌธ์„œ๋Š” ์ •์„ ์‚ฌ์šฉ๋ฒ• ๋ชฉ์ ์ž„์„ ์•ˆ๋‚ด ์ถ”๊ฐ€ โœ… ์™„๋ฃŒ
4 ๊ฐœ๋…_01_IoC_DI.md ํŒจํ‚ค์ง€ com.test.test โ†’ com.ch.basic โœ… ์™„๋ฃŒ
5 ๊ฐœ๋…_10_AOP.md ํŒจํ‚ค์ง€ com.test.test โ†’ com.ch.basic (10๊ฑด) โœ… ์™„๋ฃŒ
6 ๊ฐœ๋…_09_Exception.md @ControllerAdvice(annotations=...) ์ถ”๊ฐ€, findById ์ˆ˜์ •, @Slf4j ์ œ๊ฑฐ โœ… ์™„๋ฃŒ

๐Ÿ“Œ ๋‚จ์•„์žˆ๋Š” ๋ฏธ์ž‘์„ฑ ํ•ญ๋ชฉ

ํŒŒ์ผ ์ƒํƒœ
๊ฐœ๋…_03_JPA_Entity.md ๋ฉ”๋ชจ๋งŒ ์žˆ์Œ (๋‚ด์šฉ ๋ฏธ์ž‘์„ฑ)
๊ฐœ๋…_12_์Šค์ผ€์ฅด๋Ÿฌ.md ๋ฉ”๋ชจ๋งŒ ์žˆ์Œ (์ƒ์„ธ ๋‚ด์šฉ์€ ํ”„๋กœ์ ํŠธ_๊ตฌ์กฐ_์ •๋ฆฌ.md์— ์žˆ์Œ)

๐Ÿ“ md ๋ฌธ์„œ๋ณ„ ์ƒํƒœ ์ด์ •๋ฆฌ

ํŒŒ์ผ ๋‚ด์šฉ ์ถฉ์‹ค๋„ ์ฝ”๋“œ ์ผ์น˜ ๋น„๊ณ 
๊ฐœ๋…_00_๋ชฉ์ฐจ.md โ˜…โ˜…โ˜…โ˜…โ˜… โœ… ์ˆ˜์ • ์™„๋ฃŒ โ€” ์‹ค์ œ ํŒŒ์ผ๊ณผ ์ผ์น˜, ์ฐธ๊ณ  ๋ฌธ์„œ ์„น์…˜ ์ถ”๊ฐ€
๊ฐœ๋…_01_IoC_DI.md โ˜…โ˜…โ˜…โ˜…โ˜… โœ… ์ˆ˜์ • ์™„๋ฃŒ โ€” ํŒจํ‚ค์ง€๋ช… com.ch.basic
๊ฐœ๋…_02_MVCํŒจํ„ด.md โ˜…โ˜…โ˜…โ˜…โ˜… โœ… MVC ์ƒ์„ธ ํ๋ฆ„๋„, SSR vs CSR ๋น„๊ต
๊ฐœ๋…_03_JPA_Entity.md โ˜…โ˜…โ˜…โ˜…โ˜… โœ… JPA, Entity, Repository, QueryDSL ๊ฐœ๋… + ์ด ํ”„๋กœ์ ํŠธ ์‹ค์ œ ์ฝ”๋“œ ๊ธฐ๋ฐ˜ ์„ค๋ช…
๊ฐœ๋…_06_Transaction.md โ˜…โ˜…โ˜…โ˜…โ˜… โœ… readOnly, ์ „ํŒŒ, ๋‚ด๋ถ€ํ˜ธ์ถœ ์ฃผ์˜์‚ฌํ•ญ
๊ฐœ๋…_07_Session_Login.md โ˜…โ˜…โ˜…โ˜…โ˜… โœ… ์ˆ˜์ • ์™„๋ฃŒ โ€” LoginUserDTO ๊ธฐ์ค€, Entity ๋ฏธ์ €์žฅ ์ด์œ  ์„ค๋ช…
๊ฐœ๋…_08_Validation.md โ˜…โ˜…โ˜…โ˜…โ˜† โœ… ์ •์„ ์‚ฌ์šฉ๋ฒ• ์ •๋ฆฌ ๋ชฉ์ , ํ˜„์žฌ ์ฝ”๋“œ์™€ ์ฐจ์ด ์•ˆ๋‚ด๋จ
๊ฐœ๋…_09_Exception.md โ˜…โ˜…โ˜…โ˜…โ˜… โœ… ์ˆ˜์ • ์™„๋ฃŒ โ€” annotations ๋งค๊ฐœ๋ณ€์ˆ˜, findById
๊ฐœ๋…_10_AOP.md โ˜…โ˜…โ˜…โ˜…โ˜… โœ… ์ˆ˜์ • ์™„๋ฃŒ โ€” ํŒจํ‚ค์ง€๋ช… com.ch.basic
๊ฐœ๋…_11_Filter_Interceptor.md โ˜…โ˜…โ˜…โ˜…โ˜… โœ… ์‹ค์ œ ์ฝ”๋“œ ์ธ์šฉ, ์ ์šฉ ๋ฒ”์œ„ ์ •ํ™•
๊ฐœ๋…_12_์Šค์ผ€์ฅด๋Ÿฌ.md โ˜…โ˜…โ˜…โ˜…โ˜… โœ… @Scheduled, cron, FileCleanupScheduler ์ ์šฉ ์ฝ”๋“œ ๊ธฐ๋ฐ˜ ์„ค๋ช…
ํ”„๋กœ์ ํŠธ_๊ตฌ์กฐ_์ •๋ฆฌ.md โ˜…โ˜…โ˜…โ˜…โ˜… โœ… ์ „์ฒด ์„ค๊ณ„ ์ƒ์„ธ ๋ฌธ์„œ (์ฐธ๊ณ /์ƒ์‹์šฉ)
์„œ๋น„์Šค์„ค๊ณ„_์ •๋ฆฌ.md โ˜…โ˜…โ˜…โ˜…โ˜… - Facade ํŒจํ„ด, ๊ณ„์ธต ๊ตฌ์กฐ (์ฐธ๊ณ /์ƒ์‹์šฉ)
ํŒŒ์ผํ…Œ์ด๋ธ”์„ค๊ณ„_์ •๋ฆฌ.md โ˜…โ˜…โ˜…โ˜…โ˜… - ํ†ตํ•ฉ vs ๋ถ„๋ฆฌ, ์‹ค๋ฌด ๊ธฐ์ค€ (์ฐธ๊ณ /์ƒ์‹์šฉ)
ํ…Œ์ŠคํŠธ์ฝ”๋“œ_์ •๋ฆฌ.md โ˜…โ˜…โ˜…โ˜…โ˜† - SSR ํ…Œ์ŠคํŠธ ๊ฐ€์„ฑ๋น„ ๋ถ„์„ (์ฐธ๊ณ /์ƒ์‹์šฉ)
ํ˜‘์—….md โ˜…โ˜…โ˜†โ˜†โ˜† - ๊ฐ„๋žต ๋ฉ”๋ชจ ์ˆ˜์ค€
ํœ˜ ๊ณต๊ณต๋ฐ์ดํ„ฐAPI, CORS ์ •๋ฆฌ.md โ˜…โ˜…โ˜…โ˜…โ˜… โœ… CORS ๋™์ž‘์›๋ฆฌ, CSRF, ์„œ๋ฒ„ ์„ค์ •๋ณ„ ๋น„๊ตํ‘œ