Dev-Kyuu
article thumbnail

 ๐Ÿท DI : 

์™ธ๋ถ€์—์„œ ๋‘ ๊ฐ์ฒด๊ฐ„์˜ ๊ด€๊ณ„๋ฅผ ๊ฒฐ์ •ํ•ด์ฃผ๋Š” ๋””์ž์ธํŒจํ„ด

๊ฐ•ํ•˜๊ฒŒ ๊ฒฐํ•ฉ๋œ ํด๋ž˜์Šค๋“ค์„ ๋ถ„๋ฆฌํ•˜๊ณ , ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰ ์‹œ์ ์— ๊ฐ์ฒด๊ฐ„์˜ ๊ด€๊ณ„๋ฅผ ๊ฒฐ์ •ํ•ด์คŒ์œผ๋กœ์จ 

๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถ”๊ณ  ์œ ์—ฐ์„ฑ์„ ํ™•๋ณดํ•ด์ฃผ๋Š” ์—ญํ• ์„ ํ•จ


๐Ÿ“˜ ๊ฒฐํ•ฉ๋„๊ฐ€ ๋†’์€๊ฑด ๋ฌด์—‡์ผ๊นŒ?

๊ฒฐํ•ฉ๋„๋Š” ๋‹ค๋ฅธ ๋ชจ๋“ˆ๊ณผ์˜ ์˜์กด์„ฑ์„ ๋œปํ•จ ๋ชจ๋“ˆ ์ˆ˜์ •์„ ์œ„ํ•ด ๋‹ค๋ฅธ ๋ชจ๋“ˆ์˜ ๋ณ€๊ฒฝ์„ ์š”๊ตฌํ•˜๋Š” ์ •๋„ 

( ๋ชจ๋“ˆ์ด ๋‹ค๋ฅธ ๋ชจ๋“ˆ์— ์˜์กดํ•˜๋Š” ์ •๋„์˜ ์ฒ™๋„ or ๋ชจ๋“ˆ๊ณผ ๋ชจ๋“ˆ๊ฐ„์˜ ์ƒํ˜ธ ๊ฒฐํ•ฉ ์ •๋„๋ฅผ ๋‚˜ํƒ€๋ƒ„ )

 

  • ๊ฐ•ํ•œ ๊ฒฐํ•ฉ : 
    - ๊ฐ์ฒด ๋‚ด๋ถ€์—์„œ ๋‹ค๋ฅธ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์€ ๊ฐ•ํ•œ ๊ฒฐํ•ฉ๋„๋ฅผ ๊ฐ€์ง€๋Š” ๊ตฌ์กฐ 
    - A ํด๋ž˜์Šค ๋‚ด๋ถ€์—์„œ B๋ผ๋Š” ๊ฐ์ฒด๋ฅผ ์ง์ ‘ ์ƒ์„ฑํ•˜๊ณ  ์žˆ๋‹ค๋ฉด, B ๊ฐ์ฒด๋ฅผ C ๊ฐ์ฒด๋กœ ๋ฐ”๊พธ๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ์— Aํด๋ž˜์Šค๋„ ์ˆ˜์ •ํ•ด์•ผํ•˜๋Š”
      ๋ฐฉ์‹

 

  • ๋А์Šจํ•œ ๊ฒฐํ•ฉ 
    - ์™ธ๋ถ€์—์„œ ์ƒ์„ฑ๋œ ๊ฐ์ฒด๋ฅผ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด ๊ฐ์ฒด๋ฅผ ์ฃผ์ž…๋ฐ›๋Š” ๊ตฌ์กฐ 
    - ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถœ ์ˆ˜ ์žˆ๊ณ , ๋Ÿฐํƒ€์ž„์‹œ ์˜์กด๊ด€๊ณ„๊ฐ€ ๊ฒฐ์ •๋˜๊ธฐ ๋•Œ๋ฌธ์— ์œ ์—ฐํ•œ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง„๋‹ค.

๐Ÿ“— DI์˜ ์„ธ๊ฐ€์ง€ ์ฃผ์ž… ๋ฐฉ์‹

  1. ์ƒ์„ฑ์ž ์ฃผ์ž…
@Controller 
public class Controller{
   private final Service service;

   @Autowired 
   public Controller(Service service){
     this.service = service; 
   }
}

# ์ƒ์„ฑ์ž์— @Autowired๋ฅผ ๋ถ™์—ฌ ์˜์กด์„ฑ์„ ์ฃผ์ž…๋ฐ›๋Š” ๋ฐฉ๋ฒ•.

   2. ํ•„๋“œ ์ฃผ์ž…

@Controller
public class Controller{
  @Autowired 
  private Service service;
}

# ํ•„๋“œ์— @Autowired๋ฅผ ๋ถ™์—ฌ ์˜์กด์„ฑ์„ ์ฃผ์ž…๋ฐ›๋Š” ๋ฐฉ๋ฒ•.
# ์ƒ์„ฑ์ž ์ฃผ์ž…๊ณผ ๋‹ค๋ฅด๊ฒŒ ํ•„๋“œ๋ฅผ final๋กœ ์ •์˜ํ•  ์ˆ˜ ์—†์Œ.
# ์ฃผ์ž…์ด ๋™์‹œ์— ์ผ์–ด๋‚˜ ๊ฒน์น˜๋Š” ๊ฒฝ์šฐ ์ˆœํ™˜์ฐธ์กฐ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•จ.

   3. ์ˆ˜์ •์ž(Setter) ์ฃผ์ž…

@Controller 
public class Controller{
   private Service service;

   @Autowired 
   public setService(Service service){
     this.service = service; 
   }
}

# ์‚ฌ์šฉ์ž ์ •์˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์˜์กด๊ด€๊ณ„๋ฅผ ์ฃผ์ž…
# ๊ฐ์ฒด๊ฐ€ ๋ณ€๊ฒฝ๋  ํ•„์š”์„ฑ์ด ์žˆ์„ ๋•Œ๋งŒ ์‚ฌ์šฉ
# final ํ‚ค์›Œ๋“œ ์„ ์–ธ ๋ถˆ๊ฐ€
# ํ•จ์ˆ˜์ด๋ฆ„์ด setXX์ผ ํ•„์š”๋Š” ์—†์ง€๋งŒ, ์ผ๊ด€์„ฑ์„ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š”๊ฒŒ ์ข‹์Œ

๐Ÿ“’ 3๊ฐ€์ง€ ๋ฐฉ์‹ ์ค‘ ์–ด๋–ค ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋Š”๊ฒŒ ์ข‹์„๊นŒ?

: ์—ฌ๋Ÿฌ ๋ฐฉ์‹ ์ค‘ ์ƒ์„ฑ์ž ์ฃผ์ž… ๋ฐฉ์‹์ด ๊ฐ€์žฅ ๊ถŒ์žฅ๋˜๋Š”๋ฐ ์™œ์ผ๊นŒโ“


1) ์ˆœํ™˜ ์ฐธ์กฐ๋กœ ์ธํ•œ ์˜ค๋ฅ˜ ๊ฐ์ง€ ๊ฐ€๋Šฅ

: ์„œ๋กœ ๋‹ค๋ฅธ ๋นˆ๋“ค์ด ์„œ๋กœ ์ฐธ์กฐ๋ฅผ ๋งž๋ฌผ๋ฆฌ๊ฒŒ ์ฃผ์ž…๋˜๋ฉด์„œ ์ƒ๊ธฐ๋Š” ํ˜„์ƒ

ex ) Bean A -> Bean B ์ฐธ์กฐ / Bean B -> Bean A๋ฅผ ์ฐธ์กฐํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ ์ˆœํ™˜์ฐธ์กฐ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋จ

 

๐Ÿ‘‰ ์Šคํ”„๋ง์—์„œ ์–ด๋–ค ์Šคํ”„๋ง ๋นˆ์„ ๋จผ์ € ๋งŒ๋“ค์–ด์•ผ ํ•  ์ง€ ๊ฒฐ์ •ํ•  ์ˆ˜ ์—†๊ฒŒ ๋œ ์ƒํ™ฉ

 

๋”๋ณด๊ธฐ

1-1 ) ์ƒ์„ฑ์ž ์ฃผ์ž… ๋ฐฉ์‹์˜ ์ˆœํ™˜ ์ฐธ์กฐ ๋ฌธ์ œ

@Component
public class BeanA {
	private BeanB beanB;

	public void BeanA(BeanB beanB){
		this.beanB = beanB;
	}
}

@Component
public class BeanB {
	private BeanA beanA;

	public void BeanB(BeanA beanA){
		this.beanA = beanA;
	}
}

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ตฌ๋™ ์‹œ IOC๋Š” Bean A๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์œ„ํ•ด Bean B๋ฅผ ์ฃผ์ž…ํ•ด์ค˜์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— Bean B๋ฅผ ์ฐพ๊ณ ,

Bean B๋ฅผ ์ƒ์„ฑํ•˜๋ คํ•˜๋‹ˆ Bean A๊ฐ€ ํ•„์š”ํ•˜์—ฌ Bean A๋ฅผ ์ฐพ์œผ๋ฉด์„œ ๋ฌดํ•œ ๋ฐ˜๋ณต์ด ์ƒ๊ธฐ๊ฒŒ ๋˜์–ด ์‹คํ–‰ ์‹œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋จ

 

1-2 ) ํ•„๋“œ, Setter ์ฃผ์ž… ๋ฐฉ์‹์˜ ์ˆœํ™˜ ์ฐธ์กฐ ๋ฌธ์ œ

@Component
public class BeanA {
	@Autowired						// ํ•„๋“œ ์ฃผ์ž… ๋ฐฉ์‹
	private BeanB beanB;				

	public void run(){
		beanB.run();
	}

	public void call(){
		log.info("called BeanA");
	}
}

@Component
public class BeanB {
	@Autowired						// ํ•„๋“œ ์ฃผ์ž… ๋ฐฉ์‹
	private BeanA beanA;

	public void run(){
		log.info("Called BeanB");
		beanA.call();
	}
}
@Component
public class BeanA {
	private BeanB beanB;

	@Autowired
	public void setBeanB(BeanB beanB){
		this.beanB = beanB;
	}

	public void run(){
		beanB.run();
	}

	public void call(){
		log.info("called BeanA");
	}
}

@Component
public class BeanB {
	private BeanA beanA;

	@Autowired
	public void setBeanA(BeanA beanA){
		this.beanA = beanA;
	}

	public void run(){
		log.info("Called BeanB");
		beanA.call();
	}
}

 

๋‘ ๋ฐฉ์‹์€ ์ƒ์„ฑ์ž ์ฃผ์ž… ๋ฐฉ์‹๊ณผ ๋‹ค๋ฅด๊ฒŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ตฌ๋™ ๋‹น์‹œ์—๋Š” ํ•„์š”ํ•œ ์˜์กด์„ฑ์ด ์—†์„๋•Œ๋Š” Null ์ƒํƒœ๋กœ ์œ ์ง€ํ•˜๊ณ ,

์‹ค์ œ๋กœ ์‚ฌ์šฉํ•˜๋Š” ์‹œ์ ์— ์ฃผ์ž…์„ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ตฌ๋™ ๋‹น์‹œ์—๋Š” ์ˆœํ™˜์ฐธ์กฐ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Œ.

์ˆœํ™˜์ฐธ์กฐ๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์‹œ์ ์— ๋ฐœ์ƒํ•œ๋‹ค.

 

๐Ÿ‘‰ ์ƒ์„ฑ์ž ์ฃผ์ž…์€ ์ƒ์„ฑ์ž์—์„œ ์˜์กด๊ด€๊ณ„ ์ฃผ์ž…์ด ์ผ์–ด๋‚˜๊ธฐ ๋•Œ๋ฌธ์— ์ƒ์„ฑ์ž๊ฐ€ ์‹คํ–‰ ๋  ๋•Œ ์˜์กด ๊ฐ์ฒด์˜ Null ์—ฌ๋ถ€๋ฅผ ๊ฒ€์‚ฌํ•˜๋ฏ€๋กœ 
      ์ปดํŒŒ์ผ์‹œ์— ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œ์ผœ ๋Ÿฐํƒ€์ž„์‹œ์— ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ํฐ ๋ฌธ์ œ๋ฅผ ๋ฏธ์—ฐ์— ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Œ..!! 
      ( ํ•„๋“œ, Setter ์ฃผ์ž…์€ ์‹ค์ œ๋กœ ์‚ฌ์šฉํ•˜๋Š” ์‹œ์ ์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฏ€๋กœ ๋Ÿฐํƒ€์ž„์‹œ์— ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒ )

 

1-2 ) ์˜์กด์„ฑ ์ฃผ์ž…์ด ํ•„์š”ํ•œ ํ•„๋“œ๋ฅผ Final๋กœ ์„ ์–ธ ๊ฐ€๋Šฅ

 

- ํ•„๋“œ/Setter ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด Final๋กœ ์„ ์–ธ์ด ๋ถˆ๊ฐ€ํ•˜์—ฌ ๊ฐ์ฒด์˜ ๋ถˆ๋ณ€์„ฑ(Immutable)์„ ํ™•๋ณดํ•  ์ˆ˜ ์—†๋‹ค.

 

 

1-3 ) ํ…Œ์ŠคํŠธ์ฝ”๋“œ ์ž‘์„ฑ ์šฉ์ด

 

- ํ•„๋“œ ์ฃผ์ž…์„ ์‚ฌ์šฉํ•˜์—ฌ ์ž‘์„ฑ๋œ ํด๋ž˜์Šค๋ผ๋ฉด, ๋‹จ์œ„ ํ…Œ์ŠคํŠธ์‹œ ์˜์กด ๊ด€๊ณ„๋ฅผ ๊ฐ€์ง€๋Š” ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์ฃผ์ž…ํ•  ์ˆ˜ ์—†์Œ.
   ( ์Šคํ”„๋ง IOC๊ฐ€ ์ƒ์„ฑํ•ด์„œ ์ฃผ์ž…ํ•ด์ฃผ๋Š” ๋ฐฉ์‹์ด๊ณ , ์™ธ๋ถ€์— ๋…ธ์ถœ๋˜์–ด์žˆ๋Š”๊ฒƒ์ด ํ•˜๋‚˜๋„ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์˜์กด๊ด€๊ณ„๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋ฉ”์„œ๋“œ์˜ ๋‹จ์œ„ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด
      NullPointException์ด ๋ฐœ์ƒํ•จ)

 

 

โœจ ) ์ƒ์„ฑ์ž ์ฃผ์ž… Code๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋Š” ์œ ์šฉํ•œ ์–ด๋…ธํ…Œ์ด์…˜๋“ค 

@NoArgsConstructor - ๊ธฐ๋ณธ ์ƒ์„ฑ์ž ์ƒ์„ฑ
@AllArgsConstructor - ๋ชจ๋“  ํ•„๋“œ๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ์ƒ์„ฑ์ž ์ƒ์„ฑ
@RequiredArgsConstructor - ์ดˆ๊ธฐํ™” ๋˜์ง€ ์•Š์€ ๋ชจ๋“  final ํ•„๋“œ & @NonNull ๋งˆํฌ๊ฐ€ ์žˆ๋Š” ํ•„๋“œ๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ์ƒ์„ฑ์ž ์ƒ์„ฑ

 

profile

Dev-Kyuu

@kyuu_ng

ํฌ์ŠคํŒ…์ด ์ข‹์•˜๋‹ค๋ฉด "์ข‹์•„์š”โค๏ธ" ๋˜๋Š” "๊ตฌ๋…๐Ÿ‘๐Ÿป" ํ•ด์ฃผ์„ธ์š”!