ํต์ฌ ๋น์ฆ๋์ค ๋ก์ง๊ณผ๋ ๋ณ๊ฐ์ธ ๊ณตํต ๊ธฐ๋ฅ(ํก๋จ ๊ด์ฌ์ฌ)์ ํ๋์ ๋ชจ๋(Aspect)๋ก ๋ถ๋ฆฌํ์ฌ ๊ด๋ฆฌํ ์ ์๊ฒ ํด์ฃผ๋ ํ๋ก๊ทธ๋๋ฐ ํจ๋ฌ๋ค์
-> ํต์ฌ ๊ฐ๋ ์ "๊ด์ฌ์ฌ์ ๋ถ๋ฆฌ(Seperation of Concerns)"
๐ AOP๋ฅผ ์ ์ฉํ๋ฉด ๊ณตํต ๊ธฐ๋ฅ์ ํ๋์ ๊ณณ์์ ์ ์ํ๊ณ , ํ์ํ ํต์ฌ ๋ก์ง์ ์๋์ผ๋ก ๋ผ์๋ฃ๋ ๋ฐฉ์์ผ๋ก ์ฒ๋ฆฌํ ์ ์์
๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋จ(OOP)์ ์ญํ ์ ๋ฐ๋ผ ์ฑ ์์ ๋ถ๋ฆฌํ๋ ๋ฐ ํ์ํ์ง๋ง, ์ค์ ์์คํ ์ ์ค๊ณํ๋ค ๋ณด๋ฉด ๋ชจ๋ ๋ชจ๋์์ ๋ฐ๋ณต์ ์ผ๋ก ๋ฑ์ฅํ๋ ๋ก์ง๋ค์ด ์กด์ฌํจ
ex)
๐ ์ด๋ฌํ ์ฝ๋๋ค์ ์ฌ๋ฌ ํด๋์ค์ ๋ถ์ฐ๋์ด ๋ฐ๋ณต๋๊ธฐ ์ฝ๊ณ , OOP๋ง์ผ๋ก๋ ์ด ์ค๋ณต์ ํจ๊ณผ์ ์ผ๋ก ์ ๊ฑฐํ๊ธฐ ์ด๋ ต๊ธฐ ๋๋ฌธ
-> AOP๋ ์ด๋ฐ ๊ณตํต ๋ก์ง์ @Aspect๋ก ๋นผ์ ํ ๋ฒ์ ์ ์ฉ
๋น์ฆ๋์ค ๋ก์ง(์: "์ฑ๋ ๋ชฉ๋ก ์กฐํ", "๋ฉ์์ง ์ ์ก")๊ณผ ์ธํ๋ผ/์ด์ ๋ก์ง(์: "๊ถํ ์ฒดํฌ", "ํธ๋์ญ์ ์ฒ๋ฆฌ", "๋ชจ๋ํฐ๋ง")์ ๋ถ๋ฆฌํจ
๐ ๊ด์ฌ์ฌ ๋ถ๋ฆฌ๋ฅผ ํ์ ๋
"๋ชจ๋ write ์์ฒญ์ ํธ๋์ญ์ ์ด ์์ด์ผ ํ๋ค", "๋ชจ๋ API๋ ์์ฒญ ID๋ฅผ ๋จ๊ฒจ์ผ ํ๋ค" ๊ฐ์ ๊ท์น์ ๊ฐ๋ฐ์ ์ค์๋ก ๋น ๋จ๋ฆฌ์ง ์๋๋ก ๊ฐ์ ๋ก ์ ์ฉํ ์ ์์
Spring์ @Transactional ์์ฒด๊ฐ ๋ํ์ ์ธ AOP ํ์ฉ์
-> AOP๋ ์ด๋ฏธ Spring์์ "๊ฒ์ฆ๋ ๋ฐฉ์"์ด๊ณ , ์ค์ ์ค๋ฌด์์๋ ์์ฃผ ์ฐ์
์ํฉ
AOP ์ ์ฉ
@Around๋ก Controller ๋๋ Service ํจํค์ง๋ฅผ ํฌ์ธํธ์ปท์ผ๋ก ์ก์
ํจ๊ณผ
์ํฉ
AOP ์ ์ฉ
@Auditable(action="UPDATE_USER") ๊ฐ์ ์ ๋
ธํ
์ด์
๊ธฐ๋ฐ์ผ๋ก
์คํ ์ ํ์ ๋ณ๊ฒฝ ๋์ ID, ์ฌ์ฉ์ ID, ๊ฒฐ๊ณผ(์ฑ๊ณต/์คํจ), timestamp ๊ธฐ๋ก
ํจ๊ณผ
Client
โ
DispatcherServlet (Front Controller)
โ
HandlerMapping (์ด๋ค ์ปจํธ๋กค๋ฌ๊ฐ ์ฒ๋ฆฌํ ์ง ์ฐพ์)
โ
Controller Method ์คํ
โ
HandlerAdapter
โ
Return ๊ฐ ์ฒ๋ฆฌ
โ
ViewResolver or HttpMessageConverter
โ
Response
๐ ์ฌ๊ธฐ์ ์ค์ํ ๋ถ๊ธฐ์ ์ด ๋ฐ๋ก โ์ปจํธ๋กค๋ฌ ๋ฉ์๋์ ๋ฐํ๊ฐ์ ์ด๋ป๊ฒ ํด์ํ๋๋โ์ด๊ณ , ๊ทธ ์ฐจ์ด๋ฅผ ๋ง๋๋ ๊ฒ @Controller vs @RestController
@Controller๋ ์ ํต์ ์ธ MVC ํจํด์์ View(HTML ํ๋ฉด)๋ฅผ ๋ฐํํ ๋ ์ฃผ๋ก ์ฌ์ฉ
๐ ํ๋ฆ
@Controller
@RequestMapping("/users")
public class UserController {
@GetMapping("/{id}")
public String getUser(@PathVariable Long id, Model model) {
model.addAttribute("user", userService.findById(id));
return "user-detail"; // View ์ด๋ฆ
}
}
ํน์ง
@RestController๋ REST API ์ ์ฉ ์ปจํธ๋กค๋ฌ
์ฌ์ค ๋ด๋ถ์ ์ผ๋ก๋:
@RestController = @Controller + @ResponseBody
๐ ๋ฐํ๊ฐ์ View๋ก ํด์ํ์ง ์๊ณ HTTP Response Body์ ๊ทธ๋๋ก ์จ์ค๋๋ค.
๐ ํ๋ฆ
@RestController
@RequestMapping("/users")
public class UserApiController {
@GetMapping("/{id}")
public UserResponse getUser(@PathVariable Long id) {
return userService.findUser(id);
}
}
๐ ๋ฐํ ๊ฐ์ฒด โ Jackson ๊ฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ JSON์ผ๋ก ๋ณํ:
{
"id": 1,
"name": "kim"
}
ํน์ง