๐ŸŒนย ์ •๋ฆฌ by ์žฅ๋ฏธ(https://velog.io/@newbiekim/)

์Šคํ”„๋ง

์Šคํ”„๋ง์€ ์ž๋ฐ” ์–ธ์–ด ๊ธฐ๋ฐ˜์˜ ํ”„๋ ˆ์ž„์›Œํฌ์ด๋ฉฐ, ๊ฐ์ฒด ์ง€ํ–ฅ ์–ธ์–ด๊ฐ€ ๊ฐ€์ง„ ๊ฐ•๋ ฅํ•œ ํŠน์ง•์„ ์‚ด๋ ค๋‚ธ๋‹ค. ์ฆ‰, ์Šคํ”„๋ง์€ ์ข‹์€ ๊ฐ์ฒด ์ง€ํ–ฅ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ฃผ๋Š” ํ”„๋ ˆ์ž„์›Œํฌ๋‹ค.

์˜์กด์„ฑ ์ฃผ์ž…(DI)๊ณผ ์ œ์–ด ์—ญ์ „(IoC), ๊ด€์  ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(AOP) ์š”์†Œ๋ฅผ ํ†ตํ•ด **๋Š์Šจํ•œ ๊ฒฐํ•ฉ(Loose Coupling)**์„ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค. ์ด๋ ‡๊ฒŒ ๋Š์Šจํ•œ ๊ฒฐํ•ฉ์œผ๋กœ ๊ฐœ๋ฐœํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์šฉ์ดํ•˜๋‹ค๋Š” ์žฅ์ ์ด ์žˆ๋‹ค.


์˜์กด์„ฑ ์ฃผ์ž…(DI, Dependency Injection)

โฌ‡๏ธย DI๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์€ ์ฝ”๋“œ์˜ ๊ฒฝ์šฐ

@RestController
public class NoDIController {
	private MyService service = new MyServiceImpl();
	
	@GetMapping("/hello")
	public String getHello() {
		return service.getHello();
	}
}

Controller๋Š” โ€˜MyServiceโ€™ ๊ฐ์ฒด์— ์˜์กดํ•˜๊ฒŒ ๋œ๋‹ค.

๊ฐ์ฒด์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์–ป๊ฒŒ ๋˜๋ฉด ๊ฐ์ฒด ๊ฐ„์˜ ๊ฒฐํ•ฉ๋„๊ฐ€ ์˜ฌ๋ผ๊ฐ€๊ณ , ์ด๋Ÿฐ ์ฝ”๋“œ ์ž‘์„ฑ์€ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด Mock ๊ฐ์ฒด(๊ฐ€์งœ ๊ฐ์ฒด)๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๊ฒŒ ๋œ๋‹ค.

โฌ‡๏ธย DI๋ฅผ ์‚ฌ์šฉํ•œ ์ฝ”๋“œ์˜ ๊ฒฝ์šฐ

@Service
public class MyServiceImpl implements MyService {
	@Override
	public String getHello() {
		return "Hello";
	}
}

@RestController
public class DIController {
	MyService myService;

	@Autowired
	public DIController(MyService myService) {
		this.myService = myService;
	}

	@GetMapping("/hello")
	public String getHello() {
		return myService.getHello();
	}
}

@Service, @Autowired ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด MyService์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€์ง„๋‹ค.

์œ„์™€ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์ƒํ™ฉ์—์„œ Service ๊ฐ์ฒด๋ฅผ Mock ๊ฐ์ฒด๋กœ ๋Œ€์ฒดํ•˜์—ฌ ์‰ฝ๊ฒŒ ํ…Œ์ŠคํŠธ ํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ด€์  ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ(AOP, Aspect Oriented Programming)