๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Project ESG+AI/Tech Basics

25์ผ์ฐจ. IT ๊ฐœ๋… ์ •๋ฆฌ

by GreenJin_S2 2025. 11. 12.

 


**“์„œ๋ธŒ๋ชจ๋“ˆ(Submodule)”**์€ Git์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฐœ๋…์œผ๋กœ, ํ•œ Git ์ €์žฅ์†Œ ์•ˆ์— ๋‹ค๋ฅธ Git ์ €์žฅ์†Œ๋ฅผ ํฌํ•จ์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•์ด์—์š”.
์กฐ๊ธˆ ์‰ฝ๊ฒŒ ์„ค๋ช…ํ•˜์ž๋ฉด, ํ”„๋กœ์ ํŠธ ์•ˆ์— ๋˜ ๋‹ค๋ฅธ ๋…๋ฆฝ์ ์ธ ํ”„๋กœ์ ํŠธ๋ฅผ ๋ผ์›Œ ๋„ฃ๋Š” ๊ฒƒ์ด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ” ๊ธฐ๋ณธ ๊ฐœ๋… ์ •๋ฆฌ

๊ตฌ๋ถ„์„ค๋ช…
๋ฉ”์ธ ์ €์žฅ์†Œ(Main Repository) ์—ฌ๋Ÿฌ๋ถ„์ด ์ž‘์—…ํ•˜๋Š” ์ฃผ๋œ ํ”„๋กœ์ ํŠธ ์ €์žฅ์†Œ
์„œ๋ธŒ๋ชจ๋“ˆ(Submodule) ๋ฉ”์ธ ์ €์žฅ์†Œ ์•ˆ์— ํฌํ•จ๋œ ๋ณ„๋„์˜ Git ์ €์žฅ์†Œ (๋…๋ฆฝ์ ์œผ๋กœ ๋ฒ„์ „ ๊ด€๋ฆฌ๋จ)

๐Ÿ’ก ์˜ˆ์‹œ๋กœ ์ดํ•ดํ•˜๊ธฐ

์˜ˆ๋ฅผ ๋“ค์–ด, ์—ฌ๋Ÿฌ๋ถ„์ด ์›น์‚ฌ์ดํŠธ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค๊ณ  ์žˆ๋‹ค๊ณ  ํ•ด๋ณผ๊ฒŒ์š”.
์ด ํ”„๋กœ์ ํŠธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

 
my-website/ โ”œโ”€โ”€ frontend/ โ”œโ”€โ”€ backend/ โ””โ”€โ”€ shared-library/ ← ์—ฌ๊ธฐ์— ๊ณตํ†ต ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„œ๋ธŒ๋ชจ๋“ˆ๋กœ ์ถ”๊ฐ€

์—ฌ๊ธฐ์„œ shared-library๋Š” ๋‹ค๋ฅธ ํŒ€์ด ๊ด€๋ฆฌํ•˜๋Š” ๋ณ„๋„์˜ Git ์ €์žฅ์†Œ์ผ ์ˆ˜ ์žˆ์–ด์š”.
๊ทธ๋Ÿฐ๋ฐ ์—ฌ๋Ÿฌ๋ถ„ ํ”„๋กœ์ ํŠธ์—์„œ๋„ ๊ทธ ์ฝ”๋“œ๋ฅผ ๊ทธ๋Œ€๋กœ ์“ฐ๊ณ  ์‹ถ๋‹ค๋ฉด?
๐Ÿ‘‰ ๊ทธ๋Ÿด ๋•Œ git submodule add ๋ช…๋ น์„ ์ด์šฉํ•ด ์„œ๋ธŒ๋ชจ๋“ˆ๋กœ ์ถ”๊ฐ€ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.


โš™๏ธ ์ฃผ์š” ๋ช…๋ น์–ด

๋ช…๋ น์–ด์„ค๋ช…
git submodule add [์ €์žฅ์†Œ ์ฃผ์†Œ] [๊ฒฝ๋กœ] ์„œ๋ธŒ๋ชจ๋“ˆ ์ถ”๊ฐ€
git submodule update --init --recursive ์„œ๋ธŒ๋ชจ๋“ˆ ์ดˆ๊ธฐํ™” ๋ฐ ์—…๋ฐ์ดํŠธ
git submodule update --remote ์›๊ฒฉ ์ €์žฅ์†Œ์˜ ์ตœ์‹  ์ปค๋ฐ‹์œผ๋กœ ์—…๋ฐ์ดํŠธ
git submodule status ์„œ๋ธŒ๋ชจ๋“ˆ ์ƒํƒœ ํ™•์ธ

โš ๏ธ ์ฃผ์˜ํ•  ์ 

  • ์„œ๋ธŒ๋ชจ๋“ˆ์€ ๋ณ„๋„์˜ Git ์ €์žฅ์†Œ๋ผ์„œ, ์ปค๋ฐ‹์„ ํ•  ๋•Œ ์„œ๋ธŒ๋ชจ๋“ˆ ๋‚ด๋ถ€์˜ ๋ณ€๊ฒฝ์‚ฌํ•ญ์€ ์ž๋™์œผ๋กœ ๋ฐ˜์˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
    → ์ฆ‰, ์„œ๋ธŒ๋ชจ๋“ˆ ์•ˆ์—์„œ ์ง์ ‘ ์ปค๋ฐ‹ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ํ˜‘์—… ์‹œ์—๋Š” ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž๋„ git submodule update --init์„ ํ•ด์ค˜์•ผ ์ •์ƒ์ ์œผ๋กœ ์ฝ”๋“œ๊ฐ€ ๋ฐ›์•„์ง‘๋‹ˆ๋‹ค.

โœ… ์š”์•ฝ

์„œ๋ธŒ๋ชจ๋“ˆ = ํ”„๋กœ์ ํŠธ ์•ˆ์˜ ๋˜ ๋‹ค๋ฅธ Git ํ”„๋กœ์ ํŠธ.
๊ณตํ†ต ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‚˜ ๋ณ„๋„ ๊ด€๋ฆฌ๊ฐ€ ํ•„์š”ํ•œ ๋ถ€๋ถ„์„ ๊น”๋”ํ•˜๊ฒŒ ๋ถ„๋ฆฌํ•  ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

 


Spring AOP์— ๋Œ€ํ•ด ์•Œ์•„๋ณผ๊ฒŒ์š”.
AOP๋Š” ์Šคํ”„๋ง์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ ์ค‘ ํ•˜๋‚˜๋กœ, ๊ณตํ†ต ๊ธฐ๋Šฅ(๋กœ๊น…, ํŠธ๋žœ์žญ์…˜, ๋ณด์•ˆ ๋“ฑ)์„ ๋ชจ๋“ˆํ™”ํ•ด ์ฝ”๋“œ ์ค‘๋ณต์„ ์ค„์ด๋Š” ๊ธฐ์ˆ ์ด์—์š”.


๐ŸŒฑ AOP๋ž€?

AOP (Aspect Oriented Programming) — “๊ด€์  ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ”์ด๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค.
์‰ฝ๊ฒŒ ๋งํ•˜๋ฉด, **ํ•ต์‹ฌ ๋กœ์ง(Core Business Logic)**๊ณผ **๊ณตํ†ต ๊ด€์‹ฌ์‚ฌ(Cross-Cutting Concern)**๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹์ด์—์š”.


๐Ÿ” AOP์˜ ๊ฐœ๋… ๊ตฌ์กฐ

์šฉ์–ด์„ค๋ช…
Aspect (๊ด€์ ) ๊ณตํ†ต ๊ธฐ๋Šฅ์„ ์ •์˜ํ•œ ๋ชจ๋“ˆ (์˜ˆ: ๋กœ๊น…, ํŠธ๋žœ์žญ์…˜, ๊ถŒํ•œ ์ฒดํฌ ๋“ฑ)
Join Point (์กฐ์ธ ํฌ์ธํŠธ) AOP๊ฐ€ ์ ์šฉ๋  ์ˆ˜ ์žˆ๋Š” ์ง€์  (์˜ˆ: ๋ฉ”์„œ๋“œ ์‹คํ–‰ ์‹œ์  ๋“ฑ)
Pointcut (ํฌ์ธํŠธ์ปท) ์‹ค์ œ๋กœ AOP๋ฅผ ์ ์šฉํ•  ์ง€์ ์„ ์ง€์ •ํ•˜๋Š” ํ‘œํ˜„์‹
Advice (์–ด๋“œ๋ฐ”์ด์Šค) ์‹คํ–‰ ์‹œ์ ๋ณ„๋กœ ๋™์ž‘ํ•  ์ฝ”๋“œ (Before, After, Around ๋“ฑ)
Weaving (์œ„๋น™) Aspect๋ฅผ ์‹ค์ œ ์ฝ”๋“œ์— ์ ์šฉํ•˜๋Š” ๊ณผ์ •

๐Ÿ’ก ์˜ˆ์‹œ๋กœ ์ดํ•ดํ•˜๊ธฐ

์˜ˆ๋ฅผ ๋“ค์–ด, ์„œ๋น„์Šค ๋กœ์ง๋งˆ๋‹ค ๋กœ๊น… ์ฝ”๋“œ๋ฅผ ๋„ฃ๋Š”๋‹ค๊ณ  ์ƒ๊ฐํ•ด๋ณด์„ธ์š” ๐Ÿ‘‡

 
public void order() { System.out.println("๋กœ๊ทธ ์‹œ์ž‘"); // ํ•ต์‹ฌ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง System.out.println("๋กœ๊ทธ ๋"); }

์ด๋Ÿฐ ์ฝ”๋“œ๊ฐ€ ์—ฌ๋Ÿฌ ๊ณณ์— ๋ฐ˜๋ณต๋œ๋‹ค๋ฉด ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์–ด๋ ต๊ฒ ์ฃ ?

์ด๊ฑธ AOP๋กœ ๋ฐ”๊พธ๋ฉด ๋กœ๊น… ๊ธฐ๋Šฅ์„ ๋”ฐ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

 
@Aspect @Component public class LoggingAspect { @Before("execution(* com.example.service.*.*(..))") public void beforeLog() { System.out.println("๋กœ๊ทธ ์‹œ์ž‘"); } @After("execution(* com.example.service.*.*(..))") public void afterLog() { System.out.println("๋กœ๊ทธ ๋"); } }

๐Ÿ‘‰ ์ด์ œ ๋ชจ๋“  com.example.service ํŒจํ‚ค์ง€์˜ ๋ฉ”์„œ๋“œ ์‹คํ–‰ ์ „ํ›„๋กœ ์ž๋™์œผ๋กœ ๋กœ๊ทธ๊ฐ€ ์ฐํž™๋‹ˆ๋‹ค.


๐Ÿงฉ ์Šคํ”„๋ง์—์„œ AOP ์‚ฌ์šฉํ•˜๋Š” ์ด์œ 

์ด์œ ์„ค๋ช…
์ค‘๋ณต ์ œ๊ฑฐ ๋กœ๊น…, ํŠธ๋žœ์žญ์…˜, ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๋“ฑ์˜ ์ค‘๋ณต ์ฝ”๋“œ ์ œ๊ฑฐ
์œ ์ง€๋ณด์ˆ˜ ์šฉ์ด ๊ณตํ†ต ๊ธฐ๋Šฅ ๋ณ€๊ฒฝ ์‹œ ํ•œ ๊ณณ๋งŒ ์ˆ˜์ •
๊ด€์‹ฌ์‚ฌ ๋ถ„๋ฆฌ ํ•ต์‹ฌ ๋กœ์ง๊ณผ ๋ณด์กฐ ๋กœ์ง์„ ๊น”๋”ํ•˜๊ฒŒ ๋ถ„๋ฆฌ

โš™๏ธ ์–ด๋“œ๋ฐ”์ด์Šค(Advice) ์ข…๋ฅ˜

์ข…๋ฅ˜์‹คํ–‰ ์‹œ์ ์˜ˆ์‹œ
@Before ๋ฉ”์„œ๋“œ ์‹คํ–‰ ์ „ ์ ‘๊ทผ ๋กœ๊ทธ ๊ธฐ๋ก
@AfterReturning ์ •์ƒ ์ข…๋ฃŒ ํ›„ ๊ฒฐ๊ณผ ๋กœ๊ทธ ์ถœ๋ ฅ
@AfterThrowing ์˜ˆ์™ธ ๋ฐœ์ƒ ์‹œ ์—๋Ÿฌ ๋กœ๊ทธ ์ €์žฅ
@After ์‹คํ–‰ ํ›„(์„ฑ๊ณต/์‹คํŒจ ์ƒ๊ด€์—†์ด) ์ •๋ฆฌ ์ž‘์—…
@Around ์‹คํ–‰ ์ „ํ›„ ์ „์ฒด ์ œ์–ด ์‹คํ–‰ ์‹œ๊ฐ„ ์ธก์ •

โœ… ์š”์•ฝ

Spring AOP
๋Š” “๊ณตํ†ต ๊ด€์‹ฌ์‚ฌ ๋ถ„๋ฆฌ”๋ฅผ ํ†ตํ•ด
์ฝ”๋“œ ์ค‘๋ณต์„ ์ค„์ด๊ณ , ์œ ์ง€๋ณด์ˆ˜๋ฅผ ์‰ฝ๊ฒŒ ๋งŒ๋“œ๋Š” ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค.

์ฃผ๋กœ ๋กœ๊น…, ํŠธ๋žœ์žญ์…˜, ๋ณด์•ˆ, ์„ฑ๋Šฅ ๋ชจ๋‹ˆํ„ฐ๋ง ๋“ฑ์— ํ™œ์šฉ๋ฉ๋‹ˆ๋‹ค.

 

 


๐ŸŒณ 1. ์šฉ์–ด ์ •๋ฆฌ: ์ข…๋‹จ vs ํšก๋‹จ

๊ตฌ๋ถ„์˜๋ฏธ์˜ˆ์‹œ
์ข…๋‹จ ๊ด€์‹ฌ์‚ฌ (End Concern / Core Concern) ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํ•ต์‹ฌ ๊ธฐ๋Šฅ, ์ฆ‰ “๋ฌด์—‡์„ ํ•˜๋Š”๊ฐ€”์— ์ง‘์ค‘ํ•˜๋Š” ๋กœ์ง ์ฃผ๋ฌธ ์ฒ˜๋ฆฌ, ํšŒ์› ๊ฐ€์ž…, ๊ฒฐ์ œ ์ฒ˜๋ฆฌ ๋“ฑ
ํšก๋‹จ ๊ด€์‹ฌ์‚ฌ (Cross-Cutting Concern) ์—ฌ๋Ÿฌ ๊ณ„์ธต์ด๋‚˜ ๊ธฐ๋Šฅ์— ๊ณตํ†ต์ ์œผ๋กœ ์ ์šฉ๋˜๋Š” ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ ๋กœ๊น…, ๋ณด์•ˆ, ํŠธ๋žœ์žญ์…˜, ์˜ˆ์™ธ ์ฒ˜๋ฆฌ, ์„ฑ๋Šฅ ์ธก์ • ๋“ฑ

์ฆ‰,

  • ์ข…๋‹จ์€ “๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์˜ ๋ณธ์งˆ์ ์ธ ๊ธฐ๋Šฅ”
  • ํšก๋‹จ์€ “๋ถ€๊ฐ€์ ์ธ ๊ธฐ๋Šฅ(์—ฌ๋Ÿฌ ๊ณณ์— ๊ณตํ†ต์œผ๋กœ ํ•„์š”ํ•œ ๋ถ€๋ถ„)”
    ์ด๋ผ๊ณ  ์ดํ•ดํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

โš™๏ธ 2. ์Šคํ”„๋ง ๊ณ„์ธต๋ณ„ ๋ถ„๋ฅ˜

๊ณ„์ธต์—ญํ• ๋ถ„๋ฅ˜์ด์œ 
Controller ์‚ฌ์šฉ์ž์˜ ์š”์ฒญ์„ ๋ฐ›๊ณ  ์‘๋‹ต์„ ๋ฐ˜ํ™˜ โœ… ์ข…๋‹จ ๊ด€์‹ฌ์‚ฌ ์•ฑ์˜ ๊ธฐ๋Šฅ ํ๋ฆ„(์ž…์ถœ๋ ฅ)์„ ์ง์ ‘ ๋‹ด๋‹น
Service ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ฒ˜๋ฆฌ โœ… ์ข…๋‹จ ๊ด€์‹ฌ์‚ฌ ํ•ต์‹ฌ ๋กœ์ง์˜ ์ค‘์‹ฌ
Repository ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ ‘๊ทผ ๋ฐ ๊ด€๋ฆฌ โœ… ์ข…๋‹จ ๊ด€์‹ฌ์‚ฌ ๋น„์ฆˆ๋‹ˆ์Šค ์ˆ˜ํ–‰์„ ์œ„ํ•œ ํ•„์ˆ˜ ๋กœ์ง
Entity ๋„๋ฉ”์ธ ๋ฐ์ดํ„ฐ(๋น„์ฆˆ๋‹ˆ์Šค ๋ชจ๋ธ) ํ‘œํ˜„ โœ… ์ข…๋‹จ ๊ด€์‹ฌ์‚ฌ ๋น„์ฆˆ๋‹ˆ์Šค ๋ฐ์ดํ„ฐ์˜ ํ•ต์‹ฌ ๊ตฌ์กฐ

๋”ฐ๋ผ์„œ,
๐Ÿ‘‰ **Controller ~ Entity ๊ณ„์ธต์€ “์ข…๋‹จ ๊ด€์‹ฌ์‚ฌ”**์— ์†ํ•ฉ๋‹ˆ๋‹ค.
์ด๋“ค์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด “๋ฌด์—‡์„ ํ•˜๋Š”๊ฐ€”๋ฅผ ์ •์˜ํ•˜๋Š” ์ฃผ์ถ•์ด์—์š”.


๐Ÿงฉ 3. ๊ทธ๋Ÿผ AOP๋Š” ์–ด๋””์— ์“ฐ๋Š”๊ฐ€?

AOP๋Š” ํšก๋‹จ ๊ด€์‹ฌ์‚ฌ๋ฅผ ๋ชจ๋“ˆํ™”ํ•  ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ธฐ๋Šฅ์ด์ฃ :

  • ๋ฉ”์„œ๋“œ ์‹คํ–‰ ๋กœ๊ทธ ๋‚จ๊ธฐ๊ธฐ (@Before, @After)
  • ์„ฑ๋Šฅ ์ธก์ • (@Around)
  • ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌ (@Transactional)
  • ๋ณด์•ˆ ์ฒดํฌ (@PreAuthorize)

์ด๋Ÿฐ ๊ธฐ๋Šฅ๋“ค์€ Controller, Service, Repository ๋ชจ๋‘์— ์ ์šฉ๋  ์ˆ˜ ์žˆ์ง€๋งŒ,
๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๊ณผ๋Š” ์ง์ ‘์ ์ธ ๊ด€๋ จ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— **“ํšก๋‹จ ๊ด€์‹ฌ์‚ฌ”**๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค.


โœ… ๊ฒฐ๋ก 

Controller, Service, Repository, Entity = ์ข…๋‹จ ๊ด€์‹ฌ์‚ฌ
(์ฆ‰, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํ•ต์‹ฌ ํ๋ฆ„๊ณผ ๋กœ์ง์„ ๋‹ด๋‹น)

AOP๋กœ ์ฒ˜๋ฆฌ๋˜๋Š” ๋กœ๊น…, ๋ณด์•ˆ, ํŠธ๋žœ์žญ์…˜ ๋“ฑ = ํšก๋‹จ ๊ด€์‹ฌ์‚ฌ
(์ฆ‰, ์—ฌ๋Ÿฌ ๊ณ„์ธต์— ๊ณตํ†ต์ ์œผ๋กœ ์ ์šฉ๋˜๋Š” ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ)