From 2050e9798b4a2766da92548621fe8aeb220b475f Mon Sep 17 00:00:00 2001 From: KYS Date: Wed, 30 Oct 2024 17:32:15 +0900 Subject: [PATCH 1/2] keyword: submit week4 keyword --- keyword/chapter04/image01.png | Bin 0 -> 54257 bytes keyword/chapter04/keyword.md | 276 ++++++++++++++++++++++++++++++++++ 2 files changed, 276 insertions(+) create mode 100644 keyword/chapter04/image01.png create mode 100644 keyword/chapter04/keyword.md diff --git a/keyword/chapter04/image01.png b/keyword/chapter04/image01.png new file mode 100644 index 0000000000000000000000000000000000000000..df07a71554de1215850e1d8e92f6edc7500b1e2d GIT binary patch literal 54257 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

<In@7BN|;b=Zpj_u!!rM4@G^ve^Um15GG-&LM! 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

jl9Esge0UDPi)uV=)VH_W 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

mBv8b*XE?&E?%t})H#nK~H#yySi{?7F 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 ***์˜์กด๋Œ€์ƒ B๊ฐ€ ๋ณ€ํ•˜๋ฉด, ๊ทธ๊ฒƒ์ด A์— ์˜ํ–ฅ์„ ๋ฏธ์นœ๋‹ค.*** - ์ด์ผ๋ฏผ,ํ† ๋น„์˜ ์Šคํ”„๋ง 3.1, ์—์ด์ฝ˜(2012), p113 + +### ์˜์กด์„ฑ ์ฃผ์ž…(Dependency Injection)? +#### 1) ์˜์กด์„ฑ? +- ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋žจ์—์„œ ํด๋ž˜์Šค๋‚˜ ๋ชจ๋“ˆ ๊ฐ„์˜ ๊ด€๊ณ„๋ฅผ ์˜๋ฏธํ•œ๋‹ค. +- ํ•œ ํด๋ž˜์Šค๊ฐ€ ๋‹ค๋ฅธ ํด๋ž˜์Šค์— ์˜์กดํ•œ๋‹ค๋Š” ๊ฒƒ์€ ํ•ด๋‹น ํด๋ž˜์Šค๊ฐ€ ๋‹ค๋ฅธ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค๋‚˜ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค. + +#### 2) ์˜์กด์„ฑ ์ฃผ์ž…? +- ์˜์กด์„ฑ ์ฃผ์ž…์€ ๊ฐ์ฒด ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ์˜์กดํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ์ง์ ‘ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜ ๊ด€๋ฆฌํ•˜์ง€ ์•Š๊ณ  ***์™ธ๋ถ€์—์„œ ์ฃผ์ž…๋ฐ›๋Š” ๊ฒƒ***์„ ์˜๋ฏธํ•œ๋‹ค +- ์ฆ‰, ์˜์กด์„ฑ์„ ํด๋ž˜์Šค ๋‚ด๋ถ€์—์„œ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜ ๊ฒฐ์ •ํ•˜์ง€ ์•Š๊ณ , ์™ธ๋ถ€์—์„œ ์ฃผ์ž…๋ฐ›์•„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค +- ์˜์กด์„ฑ ์ฃผ์ž…์„ ์‚ฌ์šฉํ•˜๋ฉด ํด๋ž˜์Šค๋Š ์™ธ๋ถ€์—์„œ ์ฃผ์ž…๋ฐ›์€ ์˜์กด์„ฑ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ, ์˜์กด์„ฑ๊ณผ ํด๋ž˜์Šค ๊ฐ„์˜ ๊ฒฐํ•ฉ๋„๊ฐ€ ๋‚ฎ์•„์ง€๋ฉฐ ์œ ์—ฐ์„ฑ๊ณผ ์žฌ์‚ฌ์šฉ์„ฑ์ด ํ–ฅ์ƒ๋œ๋‹ค. +- ๊ฐ์ฒด ์ง€ํ–ฅ ์„ค๊ณ„ ์›์น™ (SOILD)์ค‘ ํ•˜๋‚˜์ธ ***์˜์กด์„ฑ ์—ญ์ „ ์›์น™(DIP)์„ ๋”ฐ๋ฅด๋Š” ๊ฒƒ***์ด๊ธฐ๋„ํ•˜๋‹ค. `(DIP != DP)` + +#### 3) Spring Boot ์—์„œ์˜ DI +- Spring Boot๋Š” Maven OR Gradle์„ ์‚ฌ์šฉํ•˜์—ฌ ํ”„๋กœ์ ํŠธ์˜ ์˜์กด์„ฑ์„ ๊ด€๋ฆฌํ•œ๋‹ค. +- Starter ํŒจํ‚ค์ง€๋Š” ํŠน์ •ํ•œ ๊ธฐ๋Šฅ ๋˜๋Š” ๋ชจ๋“ˆ์„ ํฌํ•จํ•œ ์˜์กด์„ฑ ์ง‘ํ•ฉ์œผ๋กœ, ๊ฐ„๋‹จํ•˜๊ฒŒ ํ•„์š”ํ•œ ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค€๋‹ค. +- Spring Framework๋Š” DI๋ฅผ ์ง€์›ํ•˜์—ฌ ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•˜๋Š” ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•œ๋‹ค. + - `@Autowired` ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ์˜์กด์„ฑ์„ ์ฃผ์ž…๋ฐ›์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ƒ์„ฑ์ž ์ฃผ์ž…, ์„ธํ„ฐ ์ฃผ์ž…, ํ•„๋“œ ์ฃผ์ž…๋“ฑ์˜ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ด ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ๋‹ค. + +#### 4) ์ƒ์„ฑ์ž ์ฃผ์ž… (Constructor Injection) +- ์ƒ์„ฑ์ž๋ฅผ ํ†ตํ•ด ์ฃผ์ž…ํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค. +- ์ธ์Šคํ„ด์Šค๊ฐ€ ์ƒ์„ฑ๋˜์—ˆ์„ ๋•Œ ์˜์กด์„ฑ์ด ์กด์žฌํ•˜๋Š” ๊ฒƒ์ด ๋ณด์žฅ๋˜๊ธฐ ๋•Œ๋ฌธ์—, ์˜์กด์„ฑ์˜ ์กด์žฌ์—ฌ๋ถ€๊ฐ€ ๋ณด์žฅ๋˜๊ณ  ์˜์กด์„ฑ์„ Immutableํ•˜๊ฒŒ ์ •์˜ ๊ฐ€๋Šฅํ•˜๋‹ค. +- ***Spring์—์„œ ๊ถŒ์žฅํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.*** +- `ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž๊ฐ€ 1๊ฐœ์ผ ๊ฒฝ์šฐ` >> ๊ทธ ์ƒ์„ฑ์ž๋กœ ์ฃผ์ž…๋ฐ›์„ ๊ฐ์ฒด๊ฐ€ `Bean`์œผ๋กœ ๋“ฑ๋ก๋˜์–ด ์žˆ๋‹ค๋ฉด, `@Autowired`๋ฅผ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ๋‹ค. +```java +@Service +public class UserService { + //final ๋ถ™์ด๊ธฐ ๊ฐ€๋Šฅ! + private final UserRepository userRepository; + + // @Autowired (ํ•ด๋‹น ์˜ˆ์‹œ ์ƒ๋žต ๊ฐ€๋Šฅ) + public UserService(UserRepository userRepository) { + this.userRepository = userRepository; + } +} +``` + +#### 5) ํ•„๋“œ ์ฃผ์ž…(Field Injection) +- ํ•„๋“œ์— ์˜์กด๊ด€๊ณ„๋ฅผ ์ฃผ์ž…ํ•˜๋Š” ๋ฐฉ๋ฒ• +- ***Intellij ์‚ฌ์šฉ์‹œ***, ํ•„๋“œ ์ฃผ์ž…์„ ํ•˜๋ฉด `Field injection is not recommended`๋ผ๋Š” ๊ฒฝ๊ณ  ๋ฌธ๊ตฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค! +- ์ฝ”๋“œ๊ฐ€ ๊ฐ„๊ฒฐํ•ด์ง€์ง€๋งŒ ***์™ธ๋ถ€์—์„œ ์ ‘๊ทผ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๋‹จ์ ***์ด ์กด์žฌํ•œ๋‹ค. + +```java +@Service +public class UserService { + @Autowired + private UserService userService; +} +``` + +### 6) ์ˆ˜์ •์ž ์ฃผ์ž…(Setter Injection) +- ํ•„๋“œ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋Š” setter๋ฅผ ํ†ตํ•ด ์˜์กด ๊ด€๊ณ„๋ฅผ ์ฃผ์ž…ํ•˜๋Š” ๋ฐฉ๋ฒ• +- ์ƒ์„ฑ์ž ์ฃผ์ž…๊ณผ ๋‹ค๋ฅด๊ฒŒ ์ฃผ์ž…๋ฐ›๋Š” ๊ฐ์ฒด๊ฐ€ ๋ณ€๊ฒฝ๋  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋Š” ๊ฒฝ์šฐ์— ์‚ฌ์šฉํ•œ๋‹ค. + +```java +private class UserService { + private UserRepository userRepository; + @Autowired + pulic void setUserRepository(UserRepository userRepository) { + this.userRepository = userRepository; + } +} +``` + +### 7) ์ƒ์„ฑ์ž ์ฃผ์ž… ๋ฐฉ์‹์˜ ์žฅ์  +1. ์ˆœํ™˜ ์ฐธ์กฐ ๋ฐฉ์ง€ + - ์ˆœํ™˜ ์ฐธ์กฐ?: ***A ํด๋ž˜์Šค๊ฐ€ B ํด๋ž˜์Šค์˜ Bean์„ ์ฃผ์ž…๋ฐ›๊ณ , B ํด๋ž˜์Šค๊ฐ€ A ํด๋ž˜์Šค์˜ Bean์„ ์ฃผ์ž…๋ฐ›๋Š” ์ƒํ™ฉ์ฒ˜๋Ÿผ ์„œ๋กœ ์ˆœํ™˜๋˜์–ด ์ฐธ์กฐํ•  ๊ฒฝ์šฐ ๋ฐœ์ƒ๋˜๋Š” ๋ฌธ์ œ*** +```java +@Service +public class AService { + @Autowired + private BService bService; + + public void helloA() { + bService.helloB(); + } +} + +public class BService { + @Autowired + private AService aService; + + public void helloB() { + aService.helloA(); + } +} + +/* + ๋‘ ๋ฉ”์†Œ๋“œ๋Š” ์„œ๋กœ๋ฅผ ๊ณ„์†ํ•˜์—ฌ ํ˜ธ์ถœํ•œ๋‹ค. -> StackOverflow Error๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. + ๊ทธ๋Ÿฌ๋‚˜ ์ƒ์„ฑ์ž ์ฃผ์ž…์„ ์ด์šฉํ•˜๋ฉด ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ตฌ๋™ ์‹œ์ (๊ฐ์ฒด์˜ ์ƒ์„ฑ ์‹œ์ )์— ์—๋Ÿฌ๊ฐ€ ๋ฏธ๋ฆฌ ๋ฐœ์ƒํ•œ๋‹ค + =>> ์ด๋ฅผ ํ†ตํ•ด ์„œ๋ฒ„ ์ž์ฒด๊ฐ€ ๊ตฌ๋™์ด ๋˜์ง€ ์•Š์Œ์„ ์•Œ ์ˆ˜ ์žˆ๊ณ  ๋ฐ”๋กœ ์ˆœํ™˜์ฐธ์กฐ๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค. + + ?_? ๊ทธ๋Ÿผ ์ง„์ž‘์— Autowired๋ฅผ ์ด์šฉํ•œ ํ•„๋“œ ์ฃผ์ž…์—์„œ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ตฌ๋™ ์‹œ์ ์— ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ด์•ผ ๋˜์ง€ ์•Š๋‚˜์š”? + =>> ๋นˆ์˜ ์ƒ์„ฑ๊ณผ ์กฐ๋ฆฝ(@Autowired) ์‹œ์ ์ด ๋ถ„๋ฆฌ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒ๋˜์ง€ ์•Š๋Š”๋‹ค. + Autowired๋Š” ๋ชจ๋“  ๊ฐ์ฒด์˜ ์ƒ์„ฑ์ด ์™„๋ฃŒ๋œ ํ›„์— ์กฐ๋ฆฝ(์˜์กด๊ด€๊ณ„ ์ฃผ์ž…)์ด ์ฒ˜๋ฆฌ๋œ๋‹ค. + + !_! ๋ฌผ๋ก  ์Šคํ”„๋ง๋ถ€ํŠธ 2.6๋ถ€ํ„ฐ๋Š” ์ˆœํ™˜ ์ฐธ์กฐ๊ฐ€ ๊ธฐ๋ณธ์ ์œผ๋กœ ํ—ˆ์šฉ๋˜์ง€ ์•Š๋„๋ก ๋ณ€๊ฒฝ๋˜์—ˆ๋‹ค. + =>> ๋”ฐ๋ผ์„œ ํ•„๋“œ ์ฃผ์ž…์„ ๋ฐ›์•„๋„ ์ˆœํ™˜ ์ฐธ์กฐ ๋ฐœ์ƒ์‹œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋กœ๋”ฉ ์‹œ์ ์— ์ž๋™์œผ๋กœ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. + */ +``` + +2. ํ…Œ์ŠคํŠธ ์šฉ์ด + - ํ…Œ์ŠคํŠธํ•˜๊ณ ์ž ํ•˜๋Š” ํด๋ž˜์Šค์— ํ•„๋“œ ์ฃผ์ž…์ด๋‚˜ ์ˆ˜์ •์ž ์ฃผ์ž…์œผ๋กœ ๋นˆ์ด ์ฃผ์ž…๋˜์–ด ์žˆ์œผ๋ฉด, `Mockito`๋ฅผ ํ†ตํ•ด ๋ชฉํ‚นํ•œ ํ›„ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•ด์•ผํ•œ๋‹ค. + - `Mockito`? : Mock(์ง„์งœ ๊ฐ์ฒด ์ฒ˜๋Ÿผ ๋™์ž‘ํ•˜์ง€๋งŒ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์ง์ ‘ ์ปจํŠธ๋กค ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด)์„ ์ง€์›ํ•˜๋Š” ํ”„๋ ˆ์ž„์›Œํฌ + - ***BUT***, ์ƒ์„ฑ์ž ์ฃผ์ž…์˜ ๊ฒฝ์šฐ ๋‹จ์ˆœํžˆ ์›ํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ ํ›„ ์ƒ์„ฑ์ž์— ๋„ฃ์–ด์ฃผ๋ฉด ๋์ด๋‹ค. + - ์ฆ‰ ์ƒ์„ฑ์ž ์ฃผ์ž…์„ ์‚ฌ์šฉ์‹œ, ***์ฃผ์ž…์˜ ๋Œ€์ƒ์ด ๋˜๋Š” ๊ฐ์ฒด๋ฅผ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์•ˆ์— ์ง์ ‘ `new` ์—ฐ์‚ฐ์„ ํ†ตํ•ด ์ฃผ์ž…๋  ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค.*** + +```java +@Service +public class UserService { + @Autowired + private UserRepository userRepository; + + public void register(String name) { + userRepository.add(name); + } +} + +public class UserTest { + @Test + public void test() { + UserService userService = new UserService(); + userService.register("mori"); + } +} +``` +3. final ์„ ์–ธ ๊ฐ€๋Šฅ (๋ถˆ๋ณ€์„ฑ ๋ณด์žฅ) + - ๋Ÿฐํƒ€์ž„์— ๊ฐ์ฒด ๋ถˆ๋ณ€์„ฑ์„ ๋ณด์žฅํ•œ๋‹ค. + - ๋‹ค๋ฅธ ์ฃผ์ž… ๋ฐฉ๋ฒ•์€ ๊ฐ์ฒด์˜ ์ƒ์„ฑ(์ƒ์„ฑ์ž ํ˜ธ์ถœ) ์ดํ›„์— ํ˜ธ์ถœ๋˜๋ฏ€๋กœ final ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉ X + - ***์ƒ์„ฑ์ž ์ฃผ์ž…์„ ํ†ตํ•ด ๋ณ€๊ฒฝ์˜ ๊ฐ€๋Šฅ์„ฑ ๋ฐฐ์ œ + ๋ถˆ๋ณ€์„ฑ์„ ๋ณด์žฅํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค*** + +4. ์Šคํ”„๋ง์— ๋น„์นจํˆฌ์ ์ธ ์ฝ”๋“œ ์ž‘์„ฑ + - ํ•„๋“œ ์ฃผ์ž…์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด @Autowired๋ฅผ ์ด์šฉํ•ด์•ผํ•˜๋Š”๋ฐ, ์ด๋Š” ์Šคํ”„๋ง์˜ ์–ด๋…ธํ…Œ์ด์…˜์ด๋‹ค. + - ***์ฆ‰ @Autowired๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด UserService์— ์Šคํ”„๋ง ์˜์กด์„ฑ์ด ์นจํˆฌํ•œ๋‹ค.*** + +--- + +## IoC (Inversion of Control) +> ***Donโ€™t call us, Weโ€™ll call you.*** - Hollywood principle + +### 1) IoC๋ž€? +- ***IoC๋ž€ ์ฝ”๋“œ์˜ ํ๋ฆ„์„ ์ œ์–ดํ•˜๋Š” ์ฃผ์ฒด๊ฐ€ ๋ฐ”๋€Œ๋Š” ๊ฒƒ์ด๋‹ค.*** +- ๋ณดํ†ต ํ”„๋กœ๊ทธ๋žจ์€ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ, ์˜ค๋ธŒ์ ํŠธ์˜ ์ƒ๋ช… ์ฃผ๊ธฐ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ, ๋ฉ”์†Œ๋“œ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ ๋“ฑ๋“ฑ์˜ ํ–‰์œ„๋ฅผ ํ•˜๋‚˜๋ถ€ํ„ฐ ์—ด๊นŒ์ง€ ๋ชจ๋‘ ์Šค์Šค๋กœ ์ˆ˜ํ–‰ํ•œ๋‹ค. +- IoC๋ฅผ ์ ์šฉํ•˜๋Š” ๊ฒƒ์€ ์ด๋Ÿฐ ํ๋ฆ„ ์ œ์–ด๋ฅผ ๋˜๋‹ค๋ฅธ ***์ œ 3์ž๊ฐ€ ์ˆ˜ํ–‰ํ•œ๋‹ค๋Š” ๊ฒƒ***์„ ์˜๋ฏธํ•œ๋‹ค. + +### 2) Spring์—์„œ์˜ IoC? +- Spring์€ IoC๋ฅผ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด `ApplicationContext`๋ผ๋Š” ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ œ๊ณตํ•œ๋‹ค. +- `ApplicationContext`๋Š” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์กฐ๋ฆฝํ•˜๋ฉฐ, ๊ฐ์ฒด์˜ ๋ผ์ดํ”„์‚ฌ์ดํด์„ ๊ด€๋ฆฌํ•œ๋‹ค. +- ***Spring์—์„œ์˜ IoC ๊ณผ์ •*** + - 1. ๊ฐ์ฒด ์ƒ์„ฑ ๋ฐ ๊ด€๋ฆฌ:`ApplicationContext`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋นˆ์„ ์ƒ์„ฑํ•˜๊ณ  ๊ด€๋ฆฌํ•œ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ๋นˆ์€ `Spring`์ด ์ œ์–ดํ•˜๋ฉฐ, ๊ฐœ๋ฐœ์ž๋Š” ๊ฐ์ฒด์˜ ์ƒ์„ฑ๊ณผ ๊ด€๋ฆฌ๋ฅผ ***์ง์ ‘ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๋Š”๋‹ค.*** + - 2. ์˜์กด์„ฑ ๊ด€๋ฆฌ: ๊ฐ์ฒด ๊ฐ„์˜ ์˜์กด์„ฑ์„ Spring์ด ์ฃผ์ž…(DI)ํ•œ๋‹ค. ๊ฐ์ฒด๊ฐ€ ํ•„์š”๋กœ ํ•˜๋Š” ๋‹ค๋ฅธ ๊ฐ์ฒด๋ฅผ ์ง์ ‘ ์ƒ์„ฑํ•˜๊ฑฐ๋‚˜ ์ฐพ๋Š” ๋Œ€์‹ , ***Spring ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์˜์กด์„ฑ์„ ์ฃผ์ž…ํ•ด์ฃผ๋‹ค.*** + - 3. ์ œ์–ด ํ๋ฆ„์˜ ์—ญ์ „: ๊ฐœ๋ฐœ์ž๊ฐ€ ์ฝ”๋“œ์˜ ์ œ์–ด ํ๋ฆ„์„ ๊ฒฐ์ •ํ•˜์ง€ ์•Š๊ณ , ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ๊ฐ์ฒด์˜ ๋ผ์ดํ”„์‚ฌ์ดํด ๋ฐ ํ๋ฆ„์„ ๊ด€๋ฆฌํ•œ๋‹ค. + +### 3) ๊ทธ๋Ÿผ DI๋‚˜ IoC๋‚˜ ๊ฐ™์€๊ฑฐ ์•„๋‹Œ๊ฐ€์š”? ๐Ÿ˜ฏ +> ***DI IS NOT IoC.*** +- IoC๋Š” ํ”„๋กœ๊ทธ๋žจ ์ œ์–ด๊ถŒ์„ ์—ญ์ „์‹œํ‚ค๋Š” ๊ฐœ๋…์ด๊ณ , DI๋Š” ***ํ•ด๋‹น ๊ฐœ๋…์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ๋””์ž์ธ ํŒจํ„ด ์ค‘ ํ•˜๋‚˜***์ด๋‹ค. +> As a result I think we need a more specific name for this pattern. Inversion of Control is too generic a term, and thus people find it confusing. As a result with a lot of discussion with various IoC advocates we settled on the name Dependency Injection. +> ๊ทธ ๊ฒฐ๊ณผ ์ด ํŒจํ„ด์— ๋Œ€ํ•ด ์ข€ ๋” ๊ตฌ์ฒด์ ์ธ ์ด๋ฆ„์ด ํ•„์š”ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค. Inversion of Control์€ ๋„ˆ๋ฌด ์ผ๋ฐ˜์ ์ธ ์šฉ์–ด์ด๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ๋žŒ๋“ค์€ ๊ทธ๊ฒƒ์„ ํ˜ผ๋™ํ•œ๋‹ค. ๊ทธ ๊ฒฐ๊ณผ ๋‹ค์–‘ํ•œ IoC ์˜นํ˜ธ์ž๋“ค๊ณผ ๋งŽ์€ ๋…ผ์˜๋ฅผ ๊ฑฐ์ณ Dependency Injection์ด๋ผ๋Š” ์ด๋ฆ„์„ ์ •ํ–ˆ๋‹ค. - ๋งˆํ‹ด ํŒŒ์šธ๋Ÿฌ + +### +) ํ”„๋ ˆ์ž„์›Œํฌ์™€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์ฐจ์ด: `IoC` +- ํ”„๋ ˆ์ž„์›Œํฌ(Framework)?: ์†Œํ”„ํŠธ์›จ์–ด์˜ ํŠน์ • ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ ์ƒํ˜ธ ํ˜‘๋ ฅํ•˜๋Š” ํด๋ž˜์Šค์™€ ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ง‘ํ•ฉ +- ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(Library)?: ํŠน์ • ๊ธฐ๋Šฅ์— ๋Œ€ํ•œ ๋„๊ตฌ or ํ•จ์ˆ˜๋“ค์„ ๋ชจ์€ ์ง‘ํ•ฉ +- ๋‘˜์˜ ์ฐจ์ด IoC: ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ์ „์ฒด์ ์ธ ํ๋ฆ„์„ ***์ž์ฒด์ ***์œผ๋กœ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ , ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ๊ทธ ์•ˆ์— ํ•„์š”ํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๋ฐ˜๋ฉด์— ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ํ๋ฆ„์— ๋Œ€ํ•ด ์ œ์–ด๋ฅผ ํ•˜๋ฉฐ ํ•„์š”ํ•œ ์ƒํ™ฉ์—๋งŒ ๊ฐ€์ ธ๋‹ค ์“ฐ๋Š” ๊ฒƒ์ด๋‹ค. + +--- + +## ํ”„๋ ˆ์ž„์›Œํฌ์™€ API์˜ ์ฐจ์ด +- ํ”„๋ ˆ์ž„์›Œํฌ(Framework)?: ์†Œํ”„ํŠธ์›จ์–ด์˜ ํŠน์ • ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ ์ƒํ˜ธ ํ˜‘๋ ฅํ•˜๋Š” ํด๋ž˜์Šค์™€ ์ธํ„ฐํŽ˜์ด์Šค์˜ ์ง‘ํ•ฉ +- API(Application Programming Interface)?: ์ •์˜ ๋ฐ ํ”„๋กœํ† ์ฝœ ์ง‘ํ•ฉ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‘ ์†Œํ”„ํŠธ์›จ์–ด ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์„œ๋กœ ***ํ†ต์‹  ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š”*** ๋งค๊ฐœ์ฒด + +### ์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด ์‰ฝ๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์—†์„๊นŒ์š”? ๐Ÿ˜ฏ +#### API +> - ์–ด๋–ค ์‚ฌ๋žŒ์ด ์Œ์‹์ ์„ ์ฐจ๋ ธ์Šต๋‹ˆ๋‹ค. ์†๋‹˜์€ ํ•ด๋‹น ์Œ์‹์ ์—์„œ ์ฃผ๋ฌธ์„ ํ•˜๊ฒŒ๋ฉ๋‹ˆ๋‹ค. +> - ์†๋‹˜์€ ๋ฉ”๋‰ดํŒ์„ ๋ฐ›์ง€ ๋ชปํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์†๋‹˜์€ ์›ํ•˜๋Š” ์Œ์‹์„ ์•„๋ฌด๊ฑฐ๋‚˜ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.(์˜ˆ๋ฅผ ๋“ค์–ด, ๋ฐ”๋‹ค๊ฑฐ๋ถ ์Šคํ”„..?) +> - ์†๋‹˜์€ ๋˜ํ•œ ์Œ์‹์„ ๋งŒ๋“œ๋Š” ์ผ๋ จ์˜ ๊ณผ์ •์„ ์š”์ฒญํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๊ทธ ๋ ˆ์‹œํ”ผ๋ฅผ ์†๋‹˜์ด ํ›”์น  ์ƒ๊ฐ ๋˜ํ•œ ํ•ฉ๋‹ˆ๋‹ค. + +- ์ด๋Ÿฐ ์ผ๋ จ์˜ ๊ณผ์ •์„ ๋‹นํ•œ ์Œ์‹์  ์‚ฌ์žฅ์€ ์ƒˆ๋กœ์šด ์ง์›์„ ๋“ค์—ฌ ํ™€์„ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค :( + +> - ํ™€์„ ๋‹ด๋‹นํ•˜๋Š” ์ง์›์˜ ์—ญํ• ์€ ์ •ํ•ด์ง„ ๋ฉ”๋‰ดํŒ์„ ๋ณด์—ฌ์ฃผ๊ณ , ๊ทธ ์•ˆ์—์„œ๋งŒ ์ฃผ๋ฌธ์„ ๋ฐ›๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. +> - ํ™€ ์ง์›์€ ์ฃผ๋ฌธ์„ ์Œ์‹์ ์˜ ์ฒด๊ณ„์— ๋งž๊ฒŒ ์ฃผ๋ฌธํ‘œ๋กœ ๋งŒ๋“ค์–ด ์ฃผ๋ฐฉ์— ๋ณด๋‚ด์ค๋‹ˆ๋‹ค. +> - ์ฃผ๋ฐฉ์—์„œ ๋งŒ๋“ค์–ด์ง„ ์Œ์‹์€ ํ™€ ์ง์›์„ ํ†ตํ•ด ๋ณด๋‚ด๊ณ , ํ™€ ์ง์›์€ ํ•ด๋‹น ์Œ์‹์„ ์†๋‹˜๋“ค์—๊ฒŒ ์ „๋‹ฌํ•ด์ค๋‹ˆ๋‹ค. +> - ํ™€ ์ง์›์€ ์†๋‹˜๋“ค์˜ ๋ถ€์ ์ ˆํ•œ ์ฃผ๋ฐฉ ์ ‘๊ทผ์„ ์ œํ•œํ•˜๊ณ  ์ •ํ•ด์ง„ ๋ฃฐ์„ ์ง€์ผœ์ฃผ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. + +- ***์—ฌ๊ธฐ์„œ ํ™€ ์ง์›๊ณผ ๋ฉ”๋‰ดํŒ์„ API๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ์ดํ•ด๊ฐ€ ๊ฐ„๊ฒฐํ•ด์ง‘๋‹ˆ๋‹ค.*** +- API๋Š” ์š”์ฒญ๊ณผ ์‘๋‹ต์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‘ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์„œ๋กœ ํ†ต์‹ ํ•˜๋Š” ๋ฐฉ๋ฒ•(๋ฉ”๋‰ดํŒ)์ž…๋‹ˆ๋‹ค. +- ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ด€์ ์—์„œ ์˜ˆ๋ฅผ ๋“ค์ž๋ฉด, ๊ธฐ์ƒ์ฒญ์˜ ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค๋Š” ์„œ๋ฒ„์ด๊ณ , ๊ธฐ์ƒ ์ •๋ณด ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ํด๋ผ์ด์–ธํŠธ์ž…๋‹ˆ๋‹ค. +- ๊ธฐ์ƒ ์ •๋ณด ์•ฑ์ด ์š”์ฒญ(๋ฉ”๋‰ด)๋ฅผ ๋ณด๋‚ด๋ฉด API๋Š” ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค ์‹œ์Šคํ…œ๊ณผ ๋Œ€ํ™”๋ฅผ ํ†ตํ•ด(์ฃผ๋ฌธํ‘œ) ํ•ด๋‹น ๋‚ ์”จ ์ •๋ณด(์Œ์‹)๋ฅผ ์•ฑ์— ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. +- ์˜ˆ๋ฅผ ๋“ค์–ด `Google Cloud Vision API`๋Š” ๊ตฌ๊ธ€์—์„œ ์ œ๊ณตํ•˜๋Š” ์ด๋ฏธ์ง€ ๋ถ„์„ API์ด๋‹ค. ์•ˆ์ชฝ์˜ ์„ธ์„ธํ•œ ์ฝ”๋“œ๋Š” ๋ณผ ์ˆ˜ ์—†๋‹ค. + +#### Framework +> - ์ƒˆ๋กœ์šด ์˜ˆ๋น„ ์‚ฌ์žฅ๋‹˜์ด ์น˜ํ‚จ์ง‘์„ ์ฐจ๋ฆฌ๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. +> - ํ•˜์ง€๋งŒ ์‚ฌ์žฅ๋‹˜์€ ์ด์ „์— ์ค‘์‹์ง‘์„ ํ•˜์…จ๋˜ ๋ถ„์ด๋ผ, ํ”„๋ผ์ด๋“œ ์น˜ํ‚จ์— ๋Œ€ํ•œ ์ง€์‹์ด ์ „๋ฌดํ•ฉ๋‹ˆ๋‹ค. +> - ์‚ฌ์žฅ๋‹˜์€ ์น˜ํ‚จ์ง‘์„ ๊ผญ ์ฐจ๋ฆฌ๊ณ  ์‹ถ์—ˆ๊ธฐ์—, ํ”„๋žœ์ฐจ์ด์ฆˆ ์น˜ํ‚จ์ง‘์— ๊ฐ€๋งน ๋ฌธ์˜ ์—ฐ๋ฝ์„ ํ•ฉ๋‹ˆ๋‹ค. +> - ํ”„๋žœ์ฐจ์ด์ฆˆ ์น˜ํ‚จ์ง‘์—์„œ๋Š” ํ•ด๋‹น ํšŒ์‚ฌ๊ฐ€ ์†Œ์œ ํ•œ ๋ ˆ์‹œํ”ผ๋‚˜ ๋น„๋ฒ•์— ๋Œ€ํ•ด ์•Œ๋ ค์ค๋‹ˆ๋‹ค. +> - ๋ฌผ๋ก  ์‚ฌ์žฅ๋‹˜์˜ ์ค‘์‹ ๊ฒฝ๋ ฅ์„ ์‚ด๋ ค, ์งœ์žฅ ์น˜ํ‚จ๊ฐ™์€ ํŠน๋ณ„ ๋ฉ”๋‰ด๋„ ์ถ”๊ฐ€ํ•˜์˜€์Šต๋‹ˆ๋‹ค. + +- ***์—ฌ๊ธฐ์„œ ํ”„๋žœ์ฐจ์ด์ฆˆ๊ฐ€ Framework๋ผ ์ƒ๊ฐํ•˜๋ฉด ์ดํ•ด๊ฐ€ ๊ฐ„๊ฒฐํ•ด์ง‘๋‹ˆ๋‹ค*** +- ํ”„๋žœ์ฐจ์ด์ฆˆ๋ฅผ ํ†ตํ•ด ์‚ฌ์žฅ๋‹˜์ด ์น˜ํ‚จ์ง‘์„ ์ฐจ๋ฆฌ๋“ฏ์ด, ***๊ฐœ๋ฐœ์ž๋“ค์ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฐœ๋ฐœํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๊ตฌ์กฐ๋ฅผ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.*** +- ํ”„๋žœ์ฐจ์ด์ฆˆ์˜ ๋ฃฐ, ์ธํ…Œ๋ฆฌ์–ด์™€ ์น˜ํ‚จ ๋ ˆ์‹œํ”ผ๋ฅผ ํ•จ๋ถ€๋กœ ๊ฐœ์ธ์ด ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๊ณ , ์ด๋ฅผ ๋”ฐ๋ฅผ์‹œ ์งœ์žฅ์น˜ํ‚จ ๊ฐ™์€ ํŠน์ • ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋งŒ์กฑํ• ๋งŒํ•œ ์„œ๋น„์Šค๋ฅผ ๋„ฃ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. +- `Spring` ๋˜ํ•œ ์ผ๋ จ์˜ ๊ตฌ์กฐ์™€ ๊ทœ์น™์ด ์žˆ๋Š” `java backend framework`๋ผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. + +--- + +## AOP (Aspect Oriented Programming) +### 1) AOP (๊ด€์  ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ)? +- ์–ด๋–ค ๋กœ์ง์„ ๊ธฐ์ค€์œผ๋กœ ํ•ต์‹ฌ์ ์ธ ๊ด€์ , ๋ถ€๊ฐ€์ ์ธ ๊ด€์ ์œผ๋กœ ๋‚˜๋ˆ„์–ด์„œ ๋ณด๊ณ  ๊ทธ ๊ด€์ ์„ ๊ธฐ์ค€์œผ๋กœ ๊ฐ๊ฐ ๋ชจ๋“ˆํ™”ํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค. +- `๋ชจ๋“ˆํ™”`?: ์–ด๋–ค ๊ณตํ†ต๋œ ๋กœ์ง์ด๋‚˜ ๊ธฐ๋Šฅ์„ ํ•˜๋‚˜์˜ ๋‹จ์œ„๋กœ ๋ฌถ๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค. + +### 2) AOP ์ฃผ์š” ๊ฐœ๋… +- `Aspect`: ํฉ์–ด์ง„ ๊ด€์‹ฌ์‚ฌ๋ฅผ ๋ชจ๋“ˆํ™” ํ•œ ๊ฒƒ. ์ฃผ๋กœ ๋ถ€๊ฐ€๊ธฐ๋Šฅ์„ ๋ชจ๋“ˆํ™” ํ•œ๋‹ค. +- `Target`: `Aspect`๋ฅผ ์ ์šฉํ•˜๋Š” ๊ณณ (ex. Class, Method...) +- `Advice`: ์‹ค์งˆ์ ์œผ๋กœ ์–ด๋–ค ์ผ์„ ํ•ด์•ผํ•  ์ง€์— ๋Œ€ํ•œ ๊ฒƒ, ์‹ค์งˆ์ ์ธ ๋ถ€๊ฐ€๊ธฐ๋Šฅ์„ ๋‹ด์€ ๊ตฌํ˜„์ฒด +- `JointPoint`: `Advice`๊ฐ€ ์ ์šฉ๋  ์œ„์น˜, ๋ผ์–ด๋“ค ์ˆ˜ ์žˆ๋Š” ์ง€์ . ๋ฉ”์„œ๋“œ ์ง„์ž… ์ง€์ , ์ƒ์„ฑ์ž ํ˜ธ์ถœ ์‹œ์ , ํ•„๋“œ์—์„œ ๊ฐ’์„ ๊บผ๋‚ด์˜ฌ ๋•Œ ๋“ฑ ๋‹ค์–‘ํ•œ ์‹œ์ ์— ์ ์šฉ๊ฐ€๋Šฅํ•˜๋‹ค. +- `PointCut`: `JointPoint`์˜ ์ƒ์„ธ ์ŠคํŽ™์„ ์ •์˜ํ•œ ๊ฒƒ์ด๋‹ค. *'A ๋ฉ”์„œ๋“œ์˜ ์ง„์ž… ์‹œ์ ์— ํ˜ธ์ถœํ•  ๊ฒƒ'*๊ณผ ๊ฐ™์ด ๊ตฌ์ฒด์ ์œผ๋กœ `Advice`๊ฐ€ ์‹คํ–‰๋  ์ง€์ ์„ ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. + +### 3) ์Šคํ”„๋ง AOP ํŠน์ง• +- ํ”„๋ก์‹œ ํŒจํ„ด ๊ธฐ๋ฐ˜์˜ `AOP` ๊ตฌํ˜„์ฒด, ํ”„๋ก์‹œ ๊ฐ์ฒด๋ฅผ ์“ฐ๋Š” ์ด์œ ๋Š” ์ ‘๊ทผ ์ œ์–ด ๋ฐ ๋ถ€๊ฐ€๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด์„œ์ด๋‹ค. +- ***์Šคํ”„๋ง ๋นˆ์—๋งŒ `AOP`๋ฅผ ์ ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค.*** +- ๋ชจ๋“  `AOP` ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ ์Šคํ”„๋ง IoC์™€ ์—ฐ๋™ํ•˜์—ฌ ์—”ํ„ฐํ”„๋ผ์ด์ฆˆ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ฌธ์ œ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ… ์ง€์›์ด ๋ชฉ์ ์ด๋‹ค. +- `ํ”„๋ก์‹œ ํŒจํ„ด`?: `ํ”„๋ก์‹œ ๊ฐ์ฒด`๋Š” ์›๋ž˜ ๊ฐ์ฒด๋ฅผ ๊ฐ์‹ธ๊ณ  ์žˆ๋Š” ๊ฐ์ฒด์ด๋‹ค. ์›๋ž˜์˜ ๊ฐ์ฒด์™€ ํƒ€์ž…์€ ๋™์ผํ•˜๋‹ค. ํ”„๋ก์‹œ ๊ฐ์ฒด๊ฐ€ ์›๋ž˜ ๊ฐ์ฒด๋ฅผ ๊ฐ์‹ธ์„œ client์˜ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ํ•˜๋Š” ํŒจํ„ด์ด๋‹ค. + - ํ”„๋ก์‹œ ํŒจํ„ด์„ ์“ฐ๋Š” ์ด์œ : ์ ‘๊ทผ์„ ์ œ์–ดํ•˜๊ณ  ์‹ถ๊ฑฐ๋‚˜, ๋ถ€๊ฐ€ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค. + +### 4) ์Šคํ”„๋ง์—์„œ ํƒ€์ผ“ ๋ฉ”์„œ๋“œ์˜ Aspect ์‹คํ–‰ ์‹œ์ ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋Š” ์–ด๋…ธํ…Œ์ด์…˜ +- `@Before`: Method ์‹คํ–‰ ์ „์— ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•˜๋Š” Advice +- `@After`: Method ์‹คํ–‰ ํ›„์— ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•˜๋Š” Advice +- `@AfterReturning`: Method๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ๋ฐ˜ํ™˜๋œ ํ›„์— ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•˜๋Š” Advice +- `@AfterThrowing`: Method์—์„œ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ ํ›„์— ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•˜๋Š” Advice +- `@Around`: Method ์‹คํ–‰ ์ „ํ›„์— ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•˜๊ณ , Method ์‹คํ–‰์„ ์ง์ ‘ ์ œ์–ดํ•˜๋Š” Advice + +```java +@Aspect +@Component +public class ExceptionLoggingAspect { + + @AfterThrowing(pointcut = "execution(* com.example.service.PaymentService.*(..))", throwing = "exception") + public void logException(Exception exception) { + System.out.println("Exception caught: " + exception.getMessage()); + } +} +// ํ•ด๋‹น์ฝ”๋“œ๋Š” ์˜ˆ์™ธ์ฒ˜๋ฆฌ์— ๊ด€ํ•œ ์ฝ”๋“œ์ด๋‹ค. +// @AfterThrowing์„ ํ†ตํ•ด ํ•ด๋‹น ์„œ๋น„์Šค๊ฐ€ ์ˆ˜ํ–‰ ๋ ๋•Œ, +// ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ด๋ฅผ ๋ฐœ๊ฒฌํ•˜๊ณ  logException ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•œ๋‹ค. +``` + +--- + +## ์„œ๋ธ”๋ฆฟ (Servlet) +### 1) ์„œ๋ธ”๋ฆฟ์ด๋ž€? +![์„œ๋ธ”๋ฆฟ ์˜ˆ์‹œ](image01.png) + +- ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ณ  ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ธฐ์ˆ ์ด๋‹ค. +- ๋™์  ์›นํŽ˜์ด์ง€ ์„œ๋ฒ„์—์„œ ์ˆ˜ํ–‰๋˜๋Š” ์†Œํ˜• ํ”„๋กœ๊ทธ๋žจ์ด๋‹ค. +- ๊ฐ ์‚ฌ์šฉ์ž์˜ ์š”์ฒญ์ด ์„œ๋ฒ„์˜ ํ•œ๊ฐœ์˜ ์Šค๋ ˆ๋“œ๋กœ ์ˆ˜ํ–‰๋œ๋‹ค. `JAVA Servelt`์€ ์ž๋ฐ”๋ฅผ ์‚ฌ์šฉํ•ด ์›นํŽ˜์ด์ง€๋ฅผ ๋™์ ์œผ๋กœ ์ƒ์„ฑํ•˜๋Š” ์„œ๋ฒ„๋‚ด ํ”„๋กœ๊ทธ๋žจ์ด๋‹ค. +- `JSP`์™€ ๋‹ค๋ฅด๊ฒŒ ์ž๋ฐ”์ฝ”๋“œ ์•ˆ์— HTML์„ ํฌํ•จํ•˜๊ณ  ์žˆ๋‹ค. (JSP๋Š” HTML์— ์ž๋ฐ”์ฝ”๋“œ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ๋‹ค.) + +### 2) ์„œ๋ธ”๋ฆฟ์˜ ์˜ˆ์‹œ - Login Page +> Http Request์—์„œ ์‚ฌ์šฉ์ž์˜ ID/PW๊ฐ€ ๋“ค์–ด๊ฐ„๋‹ค. +> Http Response๋กœ๋Š” ๋กœ๊ทธ์ธ ํ›„์— ํŽ˜์ด์ง€๋ฅผ ๋ณด๋‚ด์•ผ ํ•œ๋‹ค. +> ์‚ฌ์šฉ์ž์˜ ๋กœ๊ทธ์ธ ์ •๋ณด๋ฅผ ๋ฐ›์•„ ํ™•์ธํ•œ ํ›„, ๋‹ค์Œ ํŽ˜์ด์ง€๋ฅผ ๋‚ด๋ณด๋Š” ํ”„๋กœ๊ทธ๋žจ >>> ***์„œ๋ธ”๋ฆฟ*** +> ์›น์„œ๋ฒ„๋Š” ์š”์ฒญ์„ WAS์—๊ฒŒ ๋„˜๊ธฐ๊ณ , WAS๋Š” ์š”์ฒญ์— ๋”ฐ๋ฅธ ์„œ๋ธ”๋ฆฟ์„ ์‹คํ–‰ํ•œ๋‹ค. +> ์„œ๋ธ”๋ฆฟ์€ ์š”์ฒญ์— ๋Œ€ํ•œ ์‘๋‹ต์„ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ณด๋‚ธ๋‹ค. + +### 3) ์„œ๋ธ”๋ฆฟ์˜ ํŠน์ง• +- ์›น์„œ๋ฒ„๊ฐ€ ๋™์ ์ธ ํŽ˜์ด์ง€๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•๋Š”๋‹ค. +- Html์„ ์‚ฌ์šฉํ•˜์—ฌ ์š”์ฒญ์— ์‘๋‹ตํ•œ๋‹ค. +- Java Thread๋ฅผ ์ด์šฉํ•˜์—ฌ ๋™์ž‘ํ•œ๋‹ค. +- MVC ํŒจํ„ด์—์„œ ์ฃผ๋กœ Controller๋กœ ์ด์šฉ๋œ๋‹ค. +- HTTP ํ”„๋กœํ† ์ฝœ ์„œ๋น„์Šค๋ฅผ ์ง€์›ํ•˜๋Š” `javax.servlet.http.HttpServlet` ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›๋Š”๋‹ค. +- UDP๋ณด๋‹ค ์ฒ˜๋ฆฌ ์†๋„๊ฐ€ ๋Š๋ฆฌ๋‹ค. +- HTML ๋ณ€๊ฒฝ์‹œ Servlet์„ ์žฌ์ปดํŒŒ์ผ ํ•ด์•ผํ•œ๋‹ค. +- ์„œ๋ธ”๋ฆฟ์€ ์„œ๋ธ”๋ฆฟ ์ปจํ…Œ์ด๋„ˆ์—์„œ ๊ด€๋ฆฌ๋œ๋‹ค.(`new`๋กœ ์ƒ์„ฑ๋˜์ง€ ์•Š์œผ๋ฉฐ, `main()`์ด ์—†๋‹ค) + + From a373a6d6dee402c8a6d78269ce5b835b95defac3 Mon Sep 17 00:00:00 2001 From: KYS Date: Thu, 31 Oct 2024 16:58:40 +0900 Subject: [PATCH 2/2] mission: submit week4 additional mission --- mission/chapter04/java_mission.md | 344 ++++++++++++++++++++++++++++++ mission/chapter04/javaimg01.PNG | Bin 0 -> 9719 bytes mission/chapter04/javaimg02.PNG | Bin 0 -> 6439 bytes mission/chapter04/javaimg03.PNG | Bin 0 -> 15098 bytes 4 files changed, 344 insertions(+) create mode 100644 mission/chapter04/java_mission.md create mode 100644 mission/chapter04/javaimg01.PNG create mode 100644 mission/chapter04/javaimg02.PNG create mode 100644 mission/chapter04/javaimg03.PNG diff --git a/mission/chapter04/java_mission.md b/mission/chapter04/java_mission.md new file mode 100644 index 0000000..c2d7712 --- /dev/null +++ b/mission/chapter04/java_mission.md @@ -0,0 +1,344 @@ +# Chapter 4. JAVA ์ถ”๊ฐ€ ๋ฏธ์…˜๐ŸŽฏ +## ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค + +### 1) ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค(Functional Interface)? +- 1๊ฐœ์˜ `์ถ”์ƒ ๋ฉ”์†Œ๋“œ`๋ฅผ ๊ฐ–๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งํ•œ๋‹ค. +- `Java8`๋ถ€ํ„ฐ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ๊ธฐ๋ณธ ๊ตฌํ˜„์ฒด๋ฅผ ํฌํ•จํ•œ `๋””ํดํŠธ ๋ฉ”์„œ๋“œ (default method)`๋ฅผ ํฌํ•จ ํ•  ์ˆ˜ ์žˆ๋‹ค. +- `default method`๋ฟ๋งŒ ์•„๋‹ˆ๋ผ `static method`๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ ์กด์žฌํ•ด๋„ ์ถ”์ƒ ๋ฉ”์„œ๋“œ๊ฐ€ ํ•œ๊ฐœ๋ผ๋ฉด ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค์ด๋‹ค. +- ์ž๋ฐ”์˜ ๋žŒ๋‹ค ํ‘œํ˜„์‹์€ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋กœ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค. + +### 2) ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค์˜ ์˜ˆ์‹œ +- ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“ค ๋•Œ, `@FuctionalInterface` ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ, ํ•ด๋‹น ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์˜ ์กฐ๊ฑด์— ๋งž๋Š”์ง€ ๊ฒ€์‚ฌํ•ด์ค€๋‹ค. +```java +@FunctionalInterface +interface CustomInterface { + T myCall(); + + //default method๋Š” ์กฐ๊ฑด์— ๊ด€๊ณ„ ์—†๋‹ค. + default void printDefault() { + System.out.println("Hello Default Method"); + } + + // static method๋Š” ์กฐ๊ฑด์— ๊ด€๊ณ„ ์—†๋‹ค. + static void printStatic() { + System.out.println("Hello Static Method"); + } +} + +public class Main { + public static void main(String[] args) { + CustomInterface customInterface = () -> "Hello Custom"; + + String s = customInterface.myCall(); + System.out.println(s); + + customInterface.printDefault(); + + CustomInterface.printStatic(); + } +} +``` +- ์‹ค์ œ ๊ฒฐ๊ณผ +![ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค ์˜ˆ์‹œ ์‹คํ–‰ ๊ฒฐ๊ณผ](javaimg01.PNG) + +- ํ˜น์—ฌ ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค ํ˜•์‹์— ๋งž์ง€ ์•Š๋Š”๋‹ค๋ฉด?: `@FunctionalInterface`๊ฐ€ ์—๋Ÿฌ๋ฅผ ๋„์›Œ์ค€๋‹ค. +> Multiple non-overriding abstract methods found in interface +> com.practice.notepad.CustomFunctionalInterface + +### 3) JAVA์—์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณตํ•˜๋Š” Functional Interfaces +- ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ผ์ผํžˆ ๋งŒ๋“ค๊ณ  ์‚ฌ์šฉํ•˜๊ธฐ์—” ๋ถˆํŽธํ•จ์ด ์กด์žฌํ•œ๋‹ค. +- JAVA๋Š” ๊ทธ๋Ÿฐ ๋ถˆํŽธํ•จ์„ ํ•ด์†Œํ•˜๊ธฐ ์œ„ํ•ด ๊ธฐ๋ณธ์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•œ๋‹ค. + +| ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค | Descriptor | Method | +|:--------------:|:-------------:|:-------------------------:| +| Predicate | `T->boolean` | `boolean test(T t)` | +| Consumer | `T->void` | `void accept(T t)` | +| Supplier | `()->T` | `T get()` | +| Function | `T->R` | `R apply(T t)` | +| Comparator | `(T, T)->int` | `int compare(T o1, T o2)` | +| Runnable | `()->void` | `void run()` | +| Callable | `()->T` | `T call()` | + +#### 4) ๋‘ ๊ฐœ์˜ ์ธ์ž๋ฅผ ๋ฐ›๋Š” Bi ์ธํ„ฐํŽ˜์ด์Šค +- ํŠน์ • ์ธ์ž๋ฅผ ๋ฐ›๋Š” `Predicate`,`Consumer`,`Function`๋“ฑ์€ ๋‘ ๊ฐœ ์ด์ƒ์˜ ํƒ€์ž…์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ์กด์žฌํ•œ๋‹ค. + +| ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค | Descriptor | Method | +|:-----------:|:-----------------:|:------------------------:| +| BiPredicate | `(T, U)->boolean` | `boolean test(T t, U u)` | +| BiConsumer | `(T, U)->void` | `void accept(T t, U u)` | +| BiFunction | `(T, U)->R` | `R apply(T t, U u)` | + + +#### 5) Keyword Problem! +> java.util.function ํŒจํ‚ค์ง€์˜ Function์„ ์‚ฌ์šฉํ•ด์„œ Integer์„ ์ธ์ž๋กœ ๋ฐ›์•„ String์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด์ฃผ์„ธ์š”! +> Functionํด๋ž˜์Šค์˜ apply๋ฅผ ๋„ค๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ๊ตฌํ˜„ํ•ด ์ฃผ์„ธ์š” + +> 1.์ต๋ช…ํด๋ž˜์Šค ์ •์˜ +> 2.ํด๋ž˜์Šค ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด ์ƒ์†๋ฐ›์•„์„œ ์ •์˜ +> 3.๋žŒ๋‹ค์‹์œผ๋กœ ์ •์˜ +> 4.๋ฉ”์„œ๋“œ ์ฐธ์กฐ๋กœ ์ •์˜ + +```java +import java.util.function.Function; + +class MyFunction implements Function { + MyFunction() {} + + @Override + public String apply(Integer i) { + return Integer.toString(i); + } +} + + +public class Main { + public static void main(String[] args) { + //1. ์ต๋ช…ํด๋ž˜์Šค ์ •์˜ + Function function = new Function() { + @Override + public String apply(Integer t) { + return Integer.toString(t); + } + }; + System.out.println(function.apply(1000)); + + //2. ํด๋ž˜์Šค ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด ์ƒ์†๋ฐ›์•— ์ •์˜ + MyFunction myFunction = new MyFunction(); + System.out.println(myFunction.apply(1000)); + + //3. ๋žŒ๋‹ค์‹์œผ๋กœ ์ •์˜ + Function lamdaFunction = a -> Integer.toString(a); + System.out.println(lamdaFunction.apply(1000)); + + //4. ๋งค์„œ๋“œ ์ฐธ์กฐ๋กœ ์ •์˜ + System.out.println(String.valueOf(1000)); + } +} + +``` +- ์‹คํ–‰ ๊ฒฐ๊ณผ +- ![javaimg02.PNG](javaimg02.PNG) + +--- + +## Stream API +### 1) Stream API? +- JAVA8๋ถ€ํ„ฐ `Stream API`์™€ `๋žŒ๋‹ค์‹`, `ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค`๋ฅผ ์ง€์›ํ•˜๋ฉด์„œ ํ•จ์ˆ˜ํ˜•์œผ๋กœ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค. +- Stream API๋Š” ***๋ฐ์ดํ„ฐ๋ฅผ ์ถ”์ƒํ™”ํ•˜๊ณ , ์ฒ˜๋ฆฌํ•˜๋Š”๋ฐ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ํ•จ์ˆ˜๋“ค์„ ์ •์˜***ํ•œ `API`๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค. + +### 2) Stream API์˜ ํŠน์ง• +#### 1. ์›๋ณธ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๋Š”๋‹ค. +- Stream API๋Š” ์›๋ณธ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•˜์—ฌ ์›๋ณธ์˜ ๋ฐ์ดํ„ฐ๊ฐ€ ์•„๋‹Œ ๋ณ„๋„์˜ ์š”์†Œ๋“ค๋กœ Stream์„ ์ƒ์„ฑํ•œ๋‹ค. +- ์›๋ณธ์˜ ๋ฐ์ดํ„ฐ๋Š” ๋‹จ์ง€ ์ฝ๊ธฐ์šฉ์ด๋ฉฐ, ์ •๋ ฌ, ํ•„ํ„ฐ๋ง ๊ฐ™์€ ์ž‘์—…์€ ๋ณ„๋„์˜ Stream์˜ ์š”์†Œ๋“ค์—์„œ ์ฒ˜๋ฆฌ๋œ๋‹ค. + +```java + +import java.util.Arrays; +import java.util.Collections; + +String[] nameArr = {"Winter", "Karina", "Giselle", "Ningning"}; +List nameList = Arrays.asList(nameArr); + +Stream nameStream = nameList.stream(); +List sortedList = nameStream.sorted() + .collect(Collections.toList()); +``` + +#### 2. Stream์€ ***๋ฌด์กฐ๊ฑด ์ผํšŒ์šฉ***์ด๋‹ค. +- Stream API๋Š” ์ผํšŒ์šฉ์ด๊ธฐ ๋•Œ๋ฌธ์— ํ•œ๋ฒˆ ์‚ฌ์šฉ์‹œ ์žฌ์‚ฌ์šฉ์ด ๋ถˆ๊ฐ€๋Šฅ ํ•˜๋‹ค. +- Stream์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ๋Š” ์žฌ์ƒ์„ฑํ›„, ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. + +#### 3. ๋‚ด๋ถ€ ๋ฐ˜๋ณต์œผ๋กœ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•œ๋‹ค. +- Stream์„ ์ด์šฉํ•˜๋ฉด ์ฝ”๋“œ๊ฐ€ ๊ฐ„๊ฒฐํ•œ ์ด์œ ? >> `๋‚ด๋ถ€ ๋ฐ˜๋ณต` +- ๊ธฐ์กด ์ฝ”๋“œ๋Š” for์ด๋‚˜ while๊ณผ ๊ฐ™์€ ๋ฌธ๋ฒ•์„ ์‚ฌ์šฉํ•ด์•ผ ํ–ˆ์œผ๋‚˜, stream์€ ๊ทธ๋Ÿฐ ๋ฐ˜๋ณต๋ฌธ์„ ๋ฉ”์†Œ๋“œ ๋‚ด๋ถ€์— ์ˆจ๊ฒจ๋†“์•˜๋‹ค. (API์˜ ์„ฑ์งˆ) + +### 3) Stream ์ƒ์„ฑํ•˜๊ธฐ +- `Collection`์˜ `stream`์ƒ์„ฑ: `Collection`์˜ ์ธํ„ฐํŽ˜์ด์Šค์—๋Š” `stream()`์ด ์ •์˜๋˜์–ด ์žˆ๋‹ค. +- ๋”ฐ๋ผ์„œ ํ•ด๋‹น ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•œ ๊ฐ์ฒด (`List`, `Set`๋“ฑ)์€ ๋ชจ๋‘ ์ด ๋ฉ”์†Œ๋“œ๋ฅผ ์ด์šฉํ•ด stream์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. + +```java +//List๋กœ๋ถ€ํ„ฐ ์ŠคํŠธ๋ฆผ์„ ์ƒ์„ฑ +import java.util.*; +List list = Arrays.asList("a1", "b2", "c3"); +Stream listStream = list.stream(); +``` + +- `๋ฐฐ์—ด`์˜ ์›์†Œ๋“ค์„ ์†Œ์Šค๋กœ ํ•˜๋Š” `stream`์ƒ์„ฑ: `Stream`์˜ `of`๋ฉ”์†Œ๋“œ ๋˜๋Š” `Arrays`์˜ `stream` ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. + +```java +//๋ฐฐ์—ด -> ์ŠคํŠธ๋ฆผ +import java.util.*; +Stream stream = Stream.of("a", "b", "c"); +Stream stream = Stream.of(new String[] {"a", "b", "c"}); +Stream stream = Arrays.stream(new String[] {"a", "b", "c"}); +Stream stream = Arrays.stream(new String[] {"a", "b", "c"}, 0, 3); //END ๋ฒ”์œ„๋Š” ํฌํ•จํ•˜์ง€ ์•Š๋Š”๋‹ค. +``` +- ์œ„์˜ ๊ฐ์ฒด๋ฅผ ์œ„ํ•œ Stream ์™ธ์—๋„ `int`, `long`๊ณผ ๊ฐ™์€ ์›์‹œ ์ž๋ฃŒํ˜•๋“ค๋„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ํŠน์ˆ˜ ์ข…๋ฅ˜์˜ Stream(`IntStream`, `LongStream`, `DoubleStream`) ๋“ค๋„ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•˜๋‹ค. +- `IntStream`์˜ ๊ฒฝ์šฐ `range()`ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ธฐ์กด์˜ `for๋ฌธ` ๋Œ€์ฒด ๊ฐ€๋Šฅํ•˜๋‹ค. +```java +//1๋ถ€ํ„ฐ 10๊นŒ์ง€์˜ ์ˆซ์ž๋ฅผ ๊ฐ–๋Š” IntStream +IntStream stream = IntStream.range(1, 10); +``` + +### 4) Stream ๊ฐ€๊ณต(์ค‘๊ฐ„ ์—ฐ์‚ฐ) +#### [ํ•„ํ„ฐ๋ง] (Filter) +- Filter๋Š” Stream์—์„œ ์กฐ๊ฑด์— ๋งž๋Š” ๋ฐ์ดํ„ฐ๋งŒ์„ ์ •์ œํ•˜์—ฌ ๋” ์ž‘์€ ์ปฌ๋ ‰์…˜์„ ๋งŒ๋“ค์–ด๋‚ด๋Š” ์—ฐ์‚ฐ์ด๋‹ค. +```java +//String์˜ stream์—์„œ "x"๊ฐ€ ๋“ค์–ด๊ฐ„ ๋ฌธ์ž์—ด๋งŒ์„ ํฌํ•จํ•˜๋„๋ก ํ•„ํ„ฐ๋ง ํ•˜๋Š” ์˜ˆ์ œ +Stream stream = + list.stream() + .filter(name -> name.contains("x")); +``` + +#### [๋ฐ์ดํ„ฐ ๋ณ€ํ™˜] (Map) +- Map์€ ๊ธฐ์กด์˜ Stream ์š”์†Œ๋“ค์„ ๋ณ€ํ™˜ํ•˜์—ฌ ์ƒˆ๋กœ์šด Stream์„ ํ˜•์„ฑํ•˜๋Š” ์—ฐ์‚ฐ์ด๋‹ค. +- ์ง€์ •๋œ ๊ฐ’์„ ํŠน์ •ํ•œ ํ˜•ํƒœ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋ฐ ์ฃผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค. +```java +//String ์š”์†Œ๋“ค๋กœ ๊ฐ–๋Š” Stream์„ ๋ชจ๋‘ ๋Œ€๋ฌธ์ž String์˜ ์š”์†Œ๋“ค๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์˜ˆ์ œ +Stream stream = + names.stream() + .map(s -> s.toUpperCase()); +``` + +#### [์ •๋ ฌ] (Sorted) +- Stream์˜ ์š”์†Œ๋“ค์„ ์ •๋ ฌํ•˜๊ธฐ ์œ„ํ•ด sorted๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. +- ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ Comparator๋ฅผ ๋„˜๊ธธ ์ˆ˜๋„ ์žˆ๋‹ค. (๊ธฐ๋ณธ ํ˜•ํƒœ๋Š” ์˜ค๋ฆ„์ฐจ์ˆœ) + +```java +public class example { + List list = Arrays.asList("Java", "GO", "C++", "JavaScript", "Swift", "Python"); + + Stream stream1 = list.stream() + .sorted(); + //[C++, GO, Java, JavaScript, Python, Swift] + List sortedList1 = stream1.collect(Collectors.toList()); + + Stream stream2 = list.stream() + .sorted(Comparator.reverseOrder()); + + //[Swift, Python, JavaScript, Java, GO, C++] + List sortedList2 = stream2.collect(Collectors.toList()); +} +``` + +#### [์ค‘๋ณต ์ œ๊ฑฐ] (Distinct) +- Stream์˜ ์š”์†Œ๊ฐ€ ์ค‘๋ณต๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ์กด์žฌ์‹œ, ์ค‘๋ณต์„ ์ œ๊ฑฐํ•˜๊ธฐ ์œ„ํ•ด distinct ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค +- ์ด๋•Œ ์ค‘๋ณต๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฒ€์‚ฌํ•˜๊ธฐ ์œ„ํ•ด Object์˜ `equals()` Method๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. +- ๋”ฐ๋กœ ๋งŒ๋“  ํด๋ž˜์Šค๋ฅผ Stream์œผ๋กœ ์‚ฌ์šฉ์‹œ์— `equals()`, `hashcode()`๋ฅผ `Override`ํ–ˆ๋‹ค๋ฉด ํ•ด๋‹น ํด๋ž˜์Šค๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค. + +```java +List list = Arrays.asList("Java", "Java", "C++", "JavaScript", "Java", "Python"); + +Stream stream = list.stream() + .distinct(); +//[Java, C++, JavaScript, Python] +``` + +#### [ํŠน์ • ์—ฐ์‚ฐ ์ˆ˜ํ–‰] (Peek) +- Stream์˜ ์š”์†Œ๋“ค์œผ ๋Œ€์ƒ์œผ๋กœ Stream์— ์˜ํ–ฅ์„ ์ฃผ์ง€์•Š๊ณ  ํŠน์ • ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•œ peek ํ•จ์ˆ˜๊ฐ€ ์กด์žฌํ•œ๋‹ค. +- peek ํ•จ์ˆ˜๋Š” Stream์˜ ๊ฐ๊ฐ์˜ ์š”์†Œ๋“ค์— ๋Œ€ํ•ด ***ํŠน์ • ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ๋ฟ ๊ฒฐ๊ณผ์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋Š”๋‹ค.*** + +```java +import java.util.stream.IntStream; +int sum = IntStream.range(1, 10) + .peek(System.out::println) + .sum(); +``` + +### 5) Stream ์ตœ์ข… ์—ฐ์‚ฐ +#### [์ตœ๋Œ“๊ฐ’/์ตœ์†Ÿ๊ฐ’/์ดํ•ฉ/ํ‰๊ท /๊ฐฏ์ˆ˜] (Max/Min/Sum/Average/Count) +- min, max, average๋Š” Stream์ด ๋น„์–ด์žˆ๋Š” ๊ฒฝ์šฐ์—๋Š” ๊ฐ’์„ ํŠน์ •ํ•  ์ˆ˜ ์—†๋‹ค. +- ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์—, `Optional`๋กœ ๊ฐ’์ด ๋ฐ˜ํ™˜๋œ๋‹ค. + +```java +import java.util.*; +OptionalInt min = IntStream.of(1, 3, 5, 7, 9).min(); +int max = IntStream.of().max().orElse(0); +``` + +- ๋ฐ˜๋ฉด, ์ดํ•ฉ์ด๋‚˜ ๊ฐฏ์ˆ˜์˜ ๊ฒฝ์šฐ์—๋Š” ๊ฐ’์ด ๋น„์–ด์žˆ๋Š” ๊ฒฝ์šฐ 0์œผ๋กœ ํŠน์ • ๊ฐ€๋Šฅํ•˜๋‹ค +- ๋”ฐ๋ผ์„œ, `Optional`๋กœ ๋ฐ˜ํ™˜๋˜์ง€ ์•Š๊ณ  ์›์‹œ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ๊ตฌํ˜„ํ•˜์˜€๋‹ค. + +```java +long count = IntStream.of(1,3,5,7,9).count(); +long sum = LongStream.of(1,3,5,7,9).sum(); +``` + +#### [๋ฐ์ดํ„ฐ ์ˆ˜์ง‘] (collect) +- Stream์˜ ์š”์†Œ๋“ค์„ `List`, `Set`, `Map`๋“ฑ๋“ฑ์˜ ๋‹ค๋ฅธ ์ข…๋ฅ˜์˜ ๊ฒฐ๊ณผ๋กœ ์ˆ˜์ง‘ํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ์—๋Š” collect ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. + +```java +/* + * collect() : ์ŠคํŠธ๋ฆผ์˜ ์ตœ์ข…์—ฐ์‚ฐ, ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ Collector๋ฅผ ํ•„์š”๋กœ ํ•œ๋‹ค. + * Collector : ์ธํ„ฐํŽ˜์ด์Šค, collect์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ์ด ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•ด์•ผํ•œ๋‹ค. + * Collectors : ํด๋ž˜์Šค, static ๋ฉ”์†Œ๋“œ๋กœ ๋ฏธ๋ฆฌ ์ž‘์„ฑ๋œ ์ปฌ๋ ‰ํ„ฐ๋ฅผ ์ œ๊ณตํ•œ๋‹ค. + */ + +//collect์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ Collector์˜ ๊ตฌํ˜„์ฒด๊ฐ€ ์™€์•ผํ•œ๋‹ค. +Object collect(Collector collector); +``` + +#### [์กฐ๊ฑด ๊ฒ€์‚ฌ] (Match) +- Stream์˜ ์š”์†Œ๋“ค์ด ํŠน์ •ํ•œ ์กฐ๊ฑด์„ ์ถฉ์กฑํ•˜๋Š”์ง€ ๊ฒ€์‚ฌํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ์—๋Š” `match` ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. +- `anyMatch`: 1๊ฐœ์˜ ์š”์†Œ๋ผ๋„ ํ•ด๋‹น ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š”๊ฐ€? +- `allMathc`: ๋ชจ๋“  ์š”์†Œ๊ฐ€ ํ•ด๋‹น ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š”๊ฐ€? +- `nonMatch`: ๋ชจ๋“  ์š”์†Œ๊ฐ€ ํ•ด๋‹น ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜์ง€ ์•Š๋Š”๊ฐ€? + +```java +import java.util.*; +List names = Arrays.asList("Java", "Inha", "Mori"); + +boolean anyMatch = names.stream() + .anyMatch(name -> name.contains("a")); + +boolean allMatch = names.stream() + .allMatch(name -> name.length() > 2); + +boolean nonMatch = names.stream() + .noneMatch(name -> name.contains("x")); + +//result: ALL TRUE +``` + +#### [ํŠน์ • ์—ฐ์‚ฐ ์ˆ˜ํ–‰] (forEach) +- Stream์˜ ์š”์†Œ๋“ค์„ ๋Œ€์ƒ์œผ๋กœ ์–ด๋–ค ํŠน์ •ํ•œ ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๊ณ ํ”ˆ ๊ฒฝ์šฐ์—๋Š” `forEach`ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. +- `peek`์™€ ๋น„์Šทํ•œ ๋Š๋‚Œ์ด์ง€๋งŒ, `peek`๋Š” ์ค‘๊ฐ„ ์—ฐ์‚ฐ์œผ๋กœ ์‹ค์ œ์š”์†Œ๋“ค์— ๋ฐ˜์˜๋˜์ง€ ์•Š๋Š”๋‹ค. +- ํ•˜์ง€๋งŒ `forEach`๋Š” ์ตœ์ข… ์—ฐ์‚ฐ์œผ๋กœ์จ ์‹ค์ œ ์š”์†Œ๋“ค์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ๊ณ , ๋ฐ˜ํ™˜๊ฐ’์ด ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค. + +### 6) Keyword Problem! +> 1๋ถ€ํ„ฐ 10๊นŒ์ง€ ์žˆ๋Š” ์ •์ˆ˜ ๋ฐฐ์—ด์„ stream์œผ๋กœ ๋‹ค๋ฃจ๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด ์ฃผ์„ธ์š”! +> ๋ฐฐ์—ด์„ stream์œผ๋กœ ๋งŒ๋“ค์–ด ์š”์†Œ๋ฅผ ๋ชจ๋‘ 2๋ฐฐ๋กœ ๋งŒ๋“  ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ ํ›„ ์›๋ณธ ๋ฐฐ์—ด๊ณผ ์ŠคํŠธ๋ฆผ ๋ฐฐ์—ด์„ ๋น„๊ตํ•˜๊ธฐ (์ถœ๋ ฅ๋ฌธ ์‚ฌ์šฉํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค!) +> ๋ฐฐ์—ด์ค‘ ์ง์ˆ˜๋งŒ 4 + "is even number"์™€ ๊ฐ™์ด String์œผ๋กœ ๋ณ€ํ™˜ํ•œ ๋ฐฐ์—ด์„ ๋งŒ๋“ค์–ด ์ถœ๋ ฅํ•˜๊ธฐ + +```java +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class Main { + public static void main(String[] args) { + int[] numArray = IntStream.range(1, 10).toArray(); + System.out.println(Arrays.toString(numArray)); + + ArrayList doubledNumArray = Arrays.stream(numArray) + .map(n -> n*2) + .boxed() + .collect(Collectors.toCollection(ArrayList::new)); + System.out.println(doubledNumArray); + + ArrayList evenNumArray = Arrays.stream(numArray) + .filter(n -> n % 2 == 0) + .mapToObj(n -> n + " is even number") + .collect(Collectors.toCollection(ArrayList::new)); + + System.out.println(evenNumArray); + } +} +``` +- ์ถœ๋ ฅ ๊ฒฐ๊ณผ + +![javaimg03.PNG](javaimg03.PNG) + +### +์˜ˆ์ƒ์งˆ๋ฌธ! +- Stream API ์ค‘์—์„œ peek() ๋ฉ”์„œ๋“œ์™€ forEach() ๋ฉ”์„œ๋“œ์˜ ์ฐจ์ด +- YesOrNo: Equals()๋Š” ๋‘ ๊ฐœ์ฒด๊ฐ€ ๋™์ผํ•œ hashCode()๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฒฝ์šฐ ์ฐธ์ด๋‹ค. \ No newline at end of file diff --git a/mission/chapter04/javaimg01.PNG b/mission/chapter04/javaimg01.PNG new file mode 100644 index 0000000000000000000000000000000000000000..40e9a80ef227e5343340d3a41deebeb5920549ed GIT binary patch literal 9719 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 literal 0 HcmV?d00001 diff --git a/mission/chapter04/javaimg02.PNG b/mission/chapter04/javaimg02.PNG new file mode 100644 index 0000000000000000000000000000000000000000..d3e9fb03636808b1185ddc1ee1c966a1bad1935b GIT binary patch literal 6439 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 Hd