๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

SRPING

์˜์กด์„ฑ ์ฃผ์ž…(Dependency Injection) ์ข…๋ฅ˜ /@RequiredArgsConstructor

1. ์˜์กด์„ฑ ์ฃผ์ž…(Dependency Injection) ์ข…๋ฅ˜

์˜์กด์„ฑ ์ฃผ์ž…์˜ ์ข…๋ฅ˜๋กœ๋Š” Field, Setter, Constructor(์ƒ์„ฑ์ž) ๋ฐฉ์‹์ด ์žˆ๋‹ค.

1) Field Injection

public class AccountController{

	@Autowired
	AccountService accountService;
    
	@Autowired
	AccountRepository accountRepository;
}

2) Setter Injection

public class AccountConroller{
	private AccountService accountService;
	private AccountRepository accountRepository;

	@Autowired
	pubic void setAccountService(AccountService accountService){
		this.accountService = accountService;
	}
	@Autowired
	pubic void setAccountRepository(AccountRepository accountRepository){
		this.accountRepository = accountRepository;
	}
}

3) Constructor Injection

public class AccountConroller{
	private AccountService accountService;
	private AccountRepository accountRepository;

	@Autowired
	pubic void setAccountService(AccountService accountService, AccountRepository accountRepository){
		this.accountService = accountService;
		this.accountRepository = accountRepository;
	}
}

 

2. Constructor Injection ์„ ๊ถŒ์žฅํ•˜๋Š” ์ด์œ 

Spring ์—์„œ๋Š” Constructor Injection์„ ๊ถŒ์žฅํ•œ๋‹ค. 

The Spring team generally advocates constructor injection as it enables one to implement application components as immutable objects  and to ensure that required dependencies are not null . Furthermore constructor-injected components are always returned to client (calling) code in a fully initialized state. As a side note, a large number of constructor arguments is a bad code smell , implying that the class likely has too many responsibilities and should be refactored to better address proper separation of concerns.

  • ๋ถˆ๋ณ€์„ฑ(immutable)
    Constructor Injection๋งŒ ์œ ์ผํ•˜๊ฒŒ final๋กœ ์„ ์–ธ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. Field, Setter ๋ฐฉ์‹์˜ ๊ฒฝ์šฐ, finalํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ๋‚œ๋‹ค. final๋กœ ์„ ์–ธ๋œ ๊ฐ์ฒด๋Š” ์ฐธ์กฐ์— ์˜ํ•œ ๋ณ€๊ฒฝ์ด ์ด๋ฃจ์–ด ์งˆ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋กœ ์ธํ•ด ๋ฐœ์ƒ๋  ์ˆ˜ ์žˆ๋Š” ์—๋Ÿฌ๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • NULL ๋ฐฉ์ง€
    ์œ„์™€ ๊ฐ™์€ ์ด์œ ๋กœ final๋กœ ์„ ์–ธ๋œ ๋ณ€์ˆ˜๋Š” ์ค‘๊ฐ„์— ๋‹ค๋ฅธ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ ์ฃผ์ž…๋ฐ›๋Š” ๊ฐ์ฒด๊ฐ€ null์ด ์•„๋‹ˆ๋ผ๋ฉด, Null์ด ์•„๋‹˜์„ ๋ณด์žฅํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ˆœํ™˜ ์ฐธ์กฐ ๋ฐฉ์ง€
    ์ˆœํ™˜ ์ฐธ์กฐ๋ž€ Aํด๋ž˜์Šค๊ฐ€ Bํด๋ž˜์Šค๋ฅผ ์ฐธ์กฐํ•˜๊ณ  ๋‹ค์‹œ Bํด๋ž˜์Šค๊ฐ€ Aํด๋ž˜์Šค๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๊ฒฝ์šฐ๋ฅผ ๋งํ•œ๋‹ค. ์ˆœํ™˜ ์ฐธ์กฐ ๋ฌธ์ œ๋Š” ์ƒ์„ฑ์ž ์ฃผ์ž…์„ ์ด์šฉํ•  ๋•Œ ๊ฐ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค. ์„œ๋ฒ„ ์ž์ฒด๊ฐ€ ๊ตฌ๋™๋˜์ง€ ์•Š๋Š”๋‹ค.
    ์ด๋Ÿฐ ์ฐจ์ด๊ฐ€ ์žˆ๋Š” ์ด์œ ๋Š” ์ƒ์„ฑ์ž ์ฃผ์ž… ๋ฐฉ๋ฒ•์€ ํ•„๋“œ ์ฃผ์ž…์ด๋‚˜ ์ˆ˜์ •์ž ์ฃผ์ž…๊ณผ๋Š” ๋นˆ(bean)์„ ์ฃผ์ž…ํ•˜๋Š” ์ˆœ์„œ๊ฐ€ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

3. bean ์ฃผ์ž… ์ˆœ์„œ

  • Setter, Field Injection ๋ฐฉ์‹
    1) ๋ชจ๋“  ๋นˆ(bean)์„ ์šฐ์„  ๋งŒ๋“ค๊ณ  BeanFactory์— ๋“ฑ๋กํ•œ๋‹ค.
    2) ๋นˆ(bean)์„ ์ฃผ์ž… ๋ฐ›์•„์•ผ ํ•˜๋Š” A ๊ฐ์ฒด์— ํ•„์š”ํ•œ ๋นˆ(bean)๋“ค์„ ์ฃผ์ž…ํ•œ๋‹ค.
  • ์ƒ์„ฑ์ž ์ฃผ์ž…(Constructor Injection) ๋ฐฉ์‹
    1) ํด๋ž˜์Šค A ๋นˆ(bean) ์ƒ์„ฑ์‹œ ์ƒ์„ฑ์ž๋ฅผ ์ด์šฉํ•˜๋ฉฐ ์ด๋•Œ ํ•„์š”ํ•œ ๋นˆ(bean)์ธ B ๊ฐ์ฒด๋ฅผ ์ฃผ์ž…ํ•˜๋ ค๊ณ  ์‹œ๋„ํ•œ๋‹ค.
    2) ํ•„์š”ํ•œ B ๊ฐ์ฒด๋Š” ์กด์žฌํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์ด๋ฅผ ์ƒ์„ฑ์ž๋กœ ๋งŒ๋“ค๋ ค๊ณ  ์‹œ๋„ํ•œ๋‹ค.
    3) B ๊ฐ์ฒด๋„ ์ƒ์„ฑํ•˜๋Š” ์‹œ์ ์— A ๊ฐ์ฒด๊ฐ€ ํ•„์š”ํ•˜๋‹ค.
    4) ์ˆœํ™˜ ์ฐธ์กฐ๊ฐ€ ๊ฐ์ง€๋ฉ๋‹ˆ๋‹ค.

 

 

4. @RequiredArgsConstructor 

์ด ์–ด๋…ธํ…Œ์ด์…˜์€ ์ดˆ๊ธฐํ™” ๋˜์ง€์•Š์€ final  ํ•„๋“œ๋‚˜, @NonNull  ์ด ๋ถ™์€ ํ•„๋“œ์— ๋Œ€ํ•ด ์ƒ์„ฑ์ž๋ฅผ ์ƒ์„ฑํ•ด ์ค€๋‹ค.

์ƒ์„ฑ์ž๊ฐ€ ํ•˜๋‚˜๋งŒ ์žˆ๊ณ , ๊ทธ ์ƒ์„ฑ์ž๊ฐ€ ๋ฐ›๋Š” param์ด bean์œผ๋กœ ๋“ฑ๋ก๋˜์–ด ์žˆ๋‹ค๋ฉด ์ž๋™์œผ๋กœ bean์„ ์ฃผ์ž…ํ•ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— @autowired ๊ฐ™์€ ์–ด๋…ธํ…Œ์ด์…˜ ์—†์ด๋„ bean์œผ๋กœ ์˜์กด์„ฑ ์ฃผ์ž…์ด ๋œ๋‹ค.

[AS-IS]

@Component
public class AccountConroller{
	private AccountService accountService;
	private AccountRepository accountRepository;

	@Autowired
	pubic void setAccountService(AccountService accountService, AccountRepository accountRepository){
			this.accountService = accountService;
			this.accountRepository = accountRepository;
	}
}

[TO-BE]

@Component
@RequiredArgsConstructor
public class SignUpFormValidator implements Validator {

    private AccountService accountService;
    private AccountRepository accountRepository;
}

 

์ฐธ๊ณ ์ž๋ฃŒ

https://docs.spring.io/spring-framework/docs/4.3.15.RELEASE/spring-framework-reference/html/beans.html

https://velog.io/@sloools/Spring-์˜์กด์„ฑ-์ฃผ์ž…-์ข…๋ฅ˜-๋ฐRequiredArgsConstructor-์–ด๋…ธํ…Œ์ด์…˜

https://junhyunny.github.io/spring-boot/junit/reson-of-recommendation-to-use-constructor-injection/

 

 

 

 

 

 

'SRPING' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

JPA ๊ฐ์ฒด์˜ ์ƒํƒœ / @Transactional  (0) 2023.01.30
Model Binding : WebDataBinder, @InitBinder  (0) 2023.01.18
Thymeleaf  (0) 2023.01.15