๋ณธ๋ฌธ์œผ๋กœ ๊ฑด๋„ˆ๋›ฐ๊ธฐ

๐ŸŒฑ Sprout Framework

Spring์ด ๋‚ด๋ถ€์ ์œผ๋กœ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด ์ฒ˜์Œ๋ถ€ํ„ฐ ๊ตฌ์ถ•ํ•œ ๊ฒฝ๋Ÿ‰ Java ์›น ํ”„๋ ˆ์ž„์›Œํฌ

Sprout๋Š” ํ˜„๋Œ€ Java ์›น ๊ฐœ๋ฐœ์˜ ํ•ต์‹ฌ ๊ฐœ๋…๋“ค์„ ์ฒ˜์Œ๋ถ€ํ„ฐ ๊ตฌํ˜„ํ•œ ์ข…ํ•ฉ์ ์ธ ์›น ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค. ์™„์ „ํžˆ ์ž‘๋™ํ•˜๋Š” NIO ๋ฐ ํ•˜์ด๋ธŒ๋ฆฌ๋“œ ์„œ๋ฒ„์™€ ๋น„๋™๊ธฐ WebSocket ์Šคํƒ์„ ๊ฐ–์ถ”๊ณ  ์žˆ์œผ๋ฉด์„œ๋„, ๋ช…ํ™•์„ฑ, ํ•ดํ‚น ๊ฐ€๋Šฅ์„ฑ, ํ™•์žฅ์„ฑ์— ์ค‘์ ์„ ๋‘๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์™œ Sprout์ธ๊ฐ€?โ€‹

๊ต์œก ๋ชฉ์ : Spring๊ณผ ๊ฐ™์€ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ๋‚ด๋ถ€์ ์œผ๋กœ ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ์œ ์‚ฌํ•œ ๊ธฐ๋Šฅ์„ ์ฒ˜์Œ๋ถ€ํ„ฐ ๊ตฌ์ถ•ํ•ด๋ณด๋ฉฐ ์ดํ•ดํ•ฉ๋‹ˆ๋‹ค.

์ง‘์ค‘๋œ ๋ฒ”์œ„: ์ปจํ…Œ์ด๋„ˆ/AOP/์›น/์„œ๋ฒ„ ๋‚ด๋ถ€์— ์˜๋„์ ์œผ๋กœ ์ง‘์ค‘ํ•ฉ๋‹ˆ๋‹ค. ์™„์ „ํ•œ ORM์€ v1.0์˜ ๋ฒ”์œ„์—์„œ ์ œ์™ธํ•˜์—ฌ ๊ด€๋ฆฌ ๊ฐ€๋Šฅํ•œ ํ‘œ๋ฉด์ ์„ ์œ ์ง€ํ•˜๊ณ  ์ฝ”๋“œ๋ฅผ ์‰ฝ๊ฒŒ ๊ฒ€ํ† ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ฃผ์š” ๊ธฐ๋Šฅโ€‹

๐Ÿ—๏ธ IoC / DI ์ปจํ…Œ์ด๋„ˆโ€‹

  • @Component, @Service, @Controller, @Repository, @Configuration, @Aspect ์Šค์บ”
  • ์ž๋™ List<T> ์ฑ„์šฐ๊ธฐ๋ฅผ ํฌํ•จํ•œ ์ƒ์„ฑ์ž ๊ธฐ๋ฐ˜ ์ฃผ์ž…
  • ์œ„์ƒ ์ •๋ ฌ์„ ์‚ฌ์šฉํ•œ ์ˆœํ™˜ ์˜์กด์„ฑ ๊ฐ์ง€
  • ํ•ฉ๋ฆฌ์ ์ธ ๊ธฐ๋ณธ๊ฐ’์„ ์œ„ํ•œ BeanDefinitionRegistrar๋ฅผ ํ†ตํ•œ ์ž๋™ ๊ตฌ์„ฑ

๐ŸŽฏ AOP (๊ด€์  ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ)โ€‹

  • ์–ด๋…ธํ…Œ์ด์…˜ ๊ธฐ๋ฐ˜ (@Before, @After, @Around)
  • ์™€์ผ๋“œ์นด๋“œ๊ฐ€ ํฌํ•จ๋œ AspectJ ์Šคํƒ€์ผ ํฌ์ธํŠธ์ปท (*, .., ?)
  • CGLIB ์„œ๋ธŒํด๋ž˜์‹ฑ + Objenesis ํด๋ฐฑ (๊ธฐ๋ณธ ์ƒ์„ฑ์ž ๋ถˆํ•„์š”)
  • ๋Œ€์ƒ๋ณ„ ํ”„๋ก์‹œ๋ฅผ ๊ฐ€์ง„ ์ˆœ์„œํ™”๋œ ์–ด๋“œ๋ฐ”์ด์ € ์ฒด์ธ

๐ŸŒ ์›น ๊ณ„์ธตโ€‹

  • ์„ ์–ธ์  ๋ผ์šฐํŒ… (@GetMapping, @PostMapping ๋“ฑ)
  • ๊ฒฝ๋กœ ๋ณ€์ˆ˜ ({id})์™€ ์š”์ฒญ ๋งค๊ฐœ๋ณ€์ˆ˜ ๋ฐ”์ธ๋”ฉ
  • ํฌ๊ด„์ ์ธ ์ธ์ˆ˜ ๋ฆฌ์กธ๋ฒ„์™€ ์‘๋‹ต ์ฒ˜๋ฆฌ
  • @ControllerAdvice๋ฅผ ํ†ตํ•œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ

โšก ๊ณ ์„ฑ๋Šฅ ์„œ๋ฒ„โ€‹

  • java.nio.channels๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ NIO ์„œ๋ฒ„
  • ํ•˜์ด๋ธŒ๋ฆฌ๋“œ ๋ชจ๋“œ: ๊ฐ€์ƒ ์Šค๋ ˆ๋“œ๋ฅผ ํ†ตํ•œ HTTP, NIO๋ฅผ ํ†ตํ•œ WebSocket
  • ํ•™์Šต๊ณผ ๋””๋ฒ„๊น…์„ ์œ„ํ•œ ๋ธ”๋กœํ‚น ํด๋ฐฑ
  • ๊ตฌ์„ฑ ๊ฐ€๋Šฅํ•œ ์‹คํ–‰ ๋ชจ๋“œ์™€ ์Šค๋ ˆ๋“œ ์œ ํ˜•

๐Ÿ”’ ๋ณด์•ˆ ์‹œ์Šคํ…œโ€‹

  • ๋ชจ๋“ˆํ™”๋œ ์ธ์ฆ (AuthenticationManager, UserDetailsService)
  • @PreAuthorize๋ฅผ ํ†ตํ•œ ๋ฉ”์„œ๋“œ ๋ณด์•ˆ (AOP ๊ธฐ๋ฐ˜)
  • URL ๊ถŒํ•œ ๋ถ€์—ฌ์™€ ์—ญํ•  ๊ธฐ๋ฐ˜ ์ ‘๊ทผ ์ œ์–ด
  • ์š”์ฒญ๋ณ„ ThreadLocal์„ ๊ฐ€์ง„ SecurityContextHolder

๐Ÿ”Œ WebSocket ์ง€์›โ€‹

  • RFC6455 ์ค€์ˆ˜ ํ•ธ๋“œ์…ฐ์ดํฌ์™€ ํ”„๋ ˆ์ž„ ์ฒ˜๋ฆฌ
  • ์šฐ์•„ํ•œ ์—ฐ๊ฒฐ ์ฒ˜๋ฆฌ๋ฅผ ๊ฐ€์ง„ ๋…ผ๋ธ”๋กœํ‚น ์“ฐ๊ธฐ ํ
  • ๋Œ€์šฉ๋Ÿ‰ ๋ฉ”์‹œ์ง€๋ฅผ ์œ„ํ•œ ๋ถ„ํ•  ์ง€์›
  • ์ƒ๋ช…์ฃผ๊ธฐ ํ›… (@OnOpen, @OnMessage, @OnClose, @OnError)

ํ’ˆ์งˆ ๋ฐ ํ…Œ์ŠคํŠธโ€‹

577๊ฐœ ํ…Œ์ŠคํŠธ
85% ๋ผ์ธ ์ปค๋ฒ„๋ฆฌ์ง€
75% ๋ธŒ๋žœ์น˜ ์ปค๋ฒ„๋ฆฌ์ง€
0๊ฐœ ์‹คํŒจ

ํฌ๊ด„์ ์ธ ํ…Œ์ŠคํŠธ ์ŠˆํŠธ๋Š” ๋‹ค์Œ์„ ๋‹ค๋ฃน๋‹ˆ๋‹ค:

  • ํ•ต์‹ฌ ์ปจํ…Œ์ด๋„ˆ ๊ธฐ๋Šฅ (์Šค์บ”, ์ฃผ์ž…, ์ƒ๋ช…์ฃผ๊ธฐ)
  • AOP ์–ด๋“œ๋ฐ”์ด์Šค ๋นŒ๋”์™€ ์ธํ„ฐ์…‰ํ„ฐ
  • MVC ์š”์ฒญ/์‘๋‹ต ์ฒ˜๋ฆฌ
  • ๋ณด์•ˆ ์ธ์ฆ๊ณผ ๊ถŒํ•œ ๋ถ€์—ฌ
  • ์„œ๋ฒ„ ๊ตฌํ˜„ (๋ธ”๋กœํ‚น/NIO/ํ•˜์ด๋ธŒ๋ฆฌ๋“œ)
  • WebSocket ํ”„๋กœํ† ์ฝœ ์ค€์ˆ˜

์‹œ์ž‘ํ•˜๊ธฐโ€‹

๋น ๋ฅธ ์‹œ์ž‘ ๊ฐ€์ด๋“œ๋ฅผ ํ™•์ธํ•˜์—ฌ ๋ช‡ ๋ถ„ ๋งŒ์— ์‹œ์ž‘ํ•ด๋ณด์„ธ์š”.

์•„ํ‚คํ…์ฒ˜๋ฅผ ์ดํ•ดํ•˜๊ณ  ์‹ถ์œผ์‹ ๊ฐ€์š”? ์•„ํ‚คํ…์ฒ˜ ๊ฐ€์ด๋“œ๋ฅผ ํƒ์ƒ‰ํ•˜์—ฌ Sprout๊ฐ€ IoC, AOP, ์›น ์„œ๋น™์„ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„ํ•˜๋Š”์ง€ ์•Œ์•„๋ณด์„ธ์š”.

์ปค๋ฎค๋‹ˆํ‹ฐ ๋ฐ ์ง€์›โ€‹