🌱Spring IoC and DI

Dohyeon KongΒ·2023λ…„ 10μ›” 29일
0

Spring🌱

λͺ©λ‘ 보기
2/11
post-thumbnail

Spring IoC (Inversion of Control)

객체의 관리λ₯Ό μŠ€ν”„λ§ μ»¨ν…Œμ΄λ„ˆ(ν˜Ήμ€ IoC μ»¨ν…Œμ΄λ„ˆ)에 맑겨 μ œμ–΄κΆŒμ΄ λ„˜μ–΄κ°„ 것을 μ˜λ―Έν•œλ‹€.

=> μŠ€ν”„λ§μ„ μ‚¬μš©ν•˜λ©΄ 객체의 μ œμ–΄κΆŒμ„ μ»¨ν…Œμ΄λ„ˆλ‘œ λ„˜κΈ°κΈ° λ•Œλ¬Έμ— κ°œλ°œμžλŠ” λΉ„μ¦ˆλ‹ˆμŠ€ 둜직 μž‘μ„±λ§Œ μ§‘μ€‘ν•˜λ©΄ λœλ‹€.

결둠적으둜 μ œμ–΄μ˜ 역전을 톡해 μ˜μ‘΄μ„± μ£Όμž…(DI), 관점 지ν–₯ ν”„λ‘œκ·Έλž˜λ°(AOP)등이 κ°€λŠ₯해진닀.


DI μ»¨ν…Œμ΄λ„ˆπŸ€΅

μ˜μ‘΄μ„± μ£Όμž…(Dependency Injection) μ€„μ—¬μ„œ DI의 μ‹€ν˜„μ„ λ•λŠ” ν”„λ ˆμž„μ›Œν¬λ₯Ό μ˜λ―Έν•œλ‹€.

μ˜μ‘΄μ„±πŸ«±πŸΌβ€πŸ«²πŸ»

Ex)
μ‚¬μš©ν•˜λŠ” 객체 : A클래슀, μ‚¬μš©λ˜λŠ” 객체 : B클래슀

Aν΄λž˜μŠ€μ—μ„œ B클래슀λ₯Ό μ‚¬μš©ν•˜λ €λ©΄ new ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ B클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό λ§Œλ“€κ³  B 클래슀의 λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜κ²Œ λœλ‹€.

μ΄λ•Œ, Bν΄λž˜μŠ€μ—μ„œ κ΅¬ν˜„ν–ˆλ˜ λ©”μ„œλ“œλ₯Ό λ³€κ²½ν•˜λ©΄ Aν΄λž˜μŠ€μ—μ„œλ„ ν•΄λ‹Ή λ©”μ„œλ“œλ₯Ό λ³€κ²½ν•΄μ•Όν•œλ‹€.
이런 관계λ₯Ό "Aν΄λž˜μŠ€λŠ” Bν΄λž˜μŠ€μ— μ˜μ‘΄ν•œλ‹€"라고 ν•œλ‹€.


의쑴의 μœ ν˜•πŸ€”

  • 클래슀의 의쑴(κ΅¬ν˜„ 의쑴)
  • μΈν„°νŽ˜μ΄μŠ€ 의쑴

πŸ“Œν΄λž˜μŠ€μ˜ 의쑴

'μ‚¬μš©ν•˜λŠ” 객체' Aν΄λž˜μŠ€μ—μ„œ 'μ‚¬μš©λ˜λŠ” 객체'인 B클래슀의 methodX λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λŠ” 경우λ₯Ό 예둜 듀어보겠닀!

//클래슀 μ˜μ‘΄μ—μ„œ μΈμŠ€ν„΄μŠ€ 생성과 λ©”μ„œλ“œ 호좜
//ν˜„μž¬μ½”λ“œμ—μ„œλŠ”  Aν΄λž˜μŠ€μ—μ„œ new ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ B클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•œλ‹€.
//μΈμŠ€ν„΄μŠ€μ—μ„œ methodX() λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œλ‹€.
class A{
	public λ°˜ν™˜ν˜• λ©”μ„œλ“œ1(){
      B b = new B();
      b.methodX();
    }
}
class B{
	public methodX(){
    	...
    }
}

ν•΄λ‹Ή μ½”λ“œλ₯Ό μ‚¬μš©ν•˜λŠ” 도쀑 섀계가 λ³€κ²½λ˜μ–΄μ„œ 'μ‚¬μš©λ˜λŠ” 객체'λ₯Ό μƒˆλ‘­κ²Œ μƒμ„ λœ C클래슀둜 λ³€κ²½ν•˜κ³  methodY()λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λ„λ‘ λ³€κ²½ν•œλ‹€.

//클래슀 μ˜μ‘΄μ—μ„œ μΈμŠ€ν„΄μŠ€ 생성과 λ©”μ„œλ“œ 호좜
//ν˜„μž¬μ½”λ“œμ—μ„œλŠ”  Aν΄λž˜μŠ€μ—μ„œ new ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ B클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•œλ‹€.
//μΈμŠ€ν„΄μŠ€μ—μ„œ methodX() λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œλ‹€.
class A{
	public λ°˜ν™˜ν˜• λ©”μ„œλ“œ1(){
      B b = new B();
      b.methodX();
    }
}
class B{
	public methodX(){
    	...
    }
}
class C{
	public methodY(){
    	...
    }
}

μ΄λŸ¬ν•œ μƒν™©μ—μ„œ μ–΄λ–»κ²Œ A클래슀의 λ©”μ„œλ“œ1() λ©”μ„œλ“œλ₯Ό μˆ˜μ •ν•˜λŠ”μ§€ μƒκ°ν•˜λ©΄ λ‹€μŒ μ½”λ“œμ™€ 같이 λ³€κ²½ν•˜λ €κ³  생각할 것이닀.

//클래슀 μ˜μ‘΄μ—μ„œ 'μ‚¬μš©ν•˜λŠ” 객체'클래슀의 μ„Έ ꡰ데λ₯Ό μˆ˜μ •
class A{
	public λ°˜ν™˜ν˜• λ©”μ„œλ“œ1(){
      C c = new C(); //C->Bλ³€κ²½, B() -> C() λ³€κ²½
      c.methodY(); //λ³€κ²½
    }
}
  • A클래슀λ₯Ό μ„Έ ꡰ데 μˆ˜μ •ν•˜μ˜€λ‹€. 이처럼 μ‚¬μš©ν•˜λŠ” 객체 ν΄λž˜μŠ€μ—μ„œ μ‚¬μš©λ˜λŠ” 객체 클래슀의 νƒ€μž…μ„ 직접 지정해 버리면 'μ‚¬μš©λ˜λŠ” 객체' 클래슀λ₯Ό λ³€κ²½ν•  경우 이λ₯Ό μ΄μš©ν•˜κ³  μžˆλŠ” 곳을 λͺ¨λ‘ μˆ˜μ •ν•΄μ•Ό ν•œλ‹€.
  • μ΄λ ‡κ²Œ 되면 μˆ˜μ •ν•œ 뢀뢄이 λŠ˜μ–΄λ‚˜κ²Œ 될 경우 μ‹€μˆ˜κ°€ λ°œμƒν•  μœ„ν—˜μ΄ 높아진닀.
  • λ˜ν•œ, μˆ˜μ •ν•  곳이 10ꡰ데, 100ꡰ데, 1000ꡰ데에 μžˆμ„ 경우 μˆ˜μ • μž‘μ—…κ³Ό μˆ˜μ •μ— μ˜ν•œ λ™μž‘μ„ ν…ŒμŠ€νŠΈν•˜λŠ”λ° κ±Έλ¦¬λŠ” μ‹œκ°„μ΄ κΈ°ν•˜κΈ‰μˆ˜μ μœΌλ‘œ λŠ˜μ–΄λ‚  것이닀.

πŸ“ŒμΈν„°νŽ˜μ΄μŠ€ 의쑴

Ex)
IμΈν„°νŽ˜μ΄μŠ€κ°€ 있고 이것을 κ΅¬ν˜„ν•œ 'μ‚¬μš©λ˜λŠ” 객체'인 B ν΄λž˜μŠ€κ°€ μžˆλ‹€. 'μ‚¬μš©ν•˜λŠ” 객체'인 Aν΄λž˜μŠ€μ—μ„œ B클래슀의 methodX λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œλ‹€.


1. Aν΄λž˜μŠ€μ—μ„œ new ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ B클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•œλ‹€.
2. μΈμŠ€ν„΄μŠ€μ—μ„œ methodX λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œλ‹€.


μ—¬κΈ°μ„œ μ£Όμ˜ν•΄μ•Όν•  점은 Aν΄λž˜μŠ€μ—μ„œλŠ” μΈν„°νŽ˜μ΄μŠ€λ‘œ μΆ”μƒν™”λœ Iλ₯Ό μ΄μš©ν•œλ‹€λŠ” 것이닀.

//μΈν„°νŽ˜μ΄μŠ€μ— μ˜μ‘΄ν•˜λŠ” μΈμŠ€ν„΄μŠ€μ˜ 생성 및 λ©”μ„œλ“œ 호좜
class A{
	public λ°˜ν™˜ν˜• λ©”μ„œλ“œ1(){
      I i = new B(); 
      i.methodX();
    }
}

interface I{
	methodX();
}

class B implements I{
	methodX(){
    	...
    }
}

μ΄λ²ˆμ—λ„ 섀계가 λ³€κ²½λ˜μ–΄μ„œ 'μ‚¬μš©λ˜λŠ” 객체'클래슀λ₯Ό λ³€κ²½ν•˜κ²Œ 됐닀고 κ°€μ •ν•˜κ²Œ 되면 'μ‚¬μš©λ˜λŠ” 객체' C클래슀(IμΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„)λ₯Ό ν˜ΈμΆœν•΄ methodXλ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λ„λ‘ λ³€κ²½ν•œλ‹€.

//μΈν„°νŽ˜μ΄μŠ€μ— μ˜μ‘΄ν•˜λŠ” 'μ‚¬μš©λ˜λŠ” 객체'클래슀의 λ³€κ²½
class A{
	public λ°˜ν™˜ν˜• λ©”μ„œλ“œ1(){
      I i = new B(); 
      i.methodX();
    }
}

interface I{
	methodX();
}

class B implements I{
	methodX(){
    	...
    }
}
class C implements I{
	methodX(){
    	...
    }
}

A클래슀의 λ©”μ„œλ“œ1λ₯Ό μ–΄λ–»κ²Œ μˆ˜μ •ν•  것인가? λ‹€μŒ μ½”λ“œμ™€ 같이 λ³€κ²½ν•  것이닀.

//μΈν„°νŽ˜μ΄μŠ€μ— μ˜μ‘΄ν•˜λŠ” 'μ‚¬μš©ν•˜λŠ” 객체' 클래슀의 ν•œ 곳을 μˆ˜μ •
class A{
	public λ°˜ν™˜ν˜• λ©”μ„œλ“œ1(){
      I i = new C(); //B() - > C()둜 λ³€κ²½ 
      i.methodX();
    }
}

interface I{
	methodX();
}

class B implements I{
	methodX(){
    	...
    }
}
class C implements I{
	methodX(){
    	...
    }
}

클래슀의 의쑴과 달리 μΈν„°νŽ˜μ΄μŠ€μ˜ μ˜μ‘΄μ€ ν•œκ³³λ§Œ μˆ˜μ •ν•œλ‹€.
이처럼 μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ 'μ‚¬μš©λ˜λŠ” 객체'클래슀λ₯Ό λ³€κ²½ν•˜λŠ” 경우 λ‹€μŒκ³Ό 같은 이점이 μžˆλ‹€.
1. μΈν„°νŽ˜μ΄μŠ€λŠ” μ°Έμ‘°λ₯Ό λ°›λŠ” μœ ν˜•μœΌλ‘œ μ‚¬μš©ν•  수 μžˆμœΌλ―€λ‘œ λ³€μˆ˜μ˜ 이름을 λ³€κ²½ν•˜μ§€ μ•Šμ•„λ„ λœλ‹€.
2. μΈν„°νŽ˜μ΄μŠ€κ°€ μ„ μ–Έλœ λ©”μ„œλ“œλ₯Ό μ΄μš©ν•˜λ©΄ ν΄λž˜μŠ€κ°€ λ°”λ€Œμ–΄λ„ λ©”μ„œλ“œλͺ…을 λ³€κ²½ν•˜μ§€ μ•Šμ•„λ„ λœλ‹€.


μ˜μ‘΄μ„± μ£Όμž…πŸ’‰

μ˜μ‘΄μ„± μ£Όμž…μ΄λž€ 'μ˜μ‘΄ν•˜λŠ” 뢀뢄을 μ™ΈλΆ€μ—μ„œ μ£Όμž…ν•˜λŠ” 것'이닀.

'μ˜μ‘΄ν•˜λŠ” 뢀뢄을 μ™ΈλΆ€μ—μ„œ μ£Όμž…ν•˜λŠ” 것'μ΄λΌλŠ” λ¬Έμž₯을 보면

  • μ˜μ‘΄ν•˜λŠ” λΆ€λΆ„μ΄λž€ 'μ‚¬μš©ν•˜λŠ” 객체' ν΄λž˜μŠ€μ— μ‚¬μš©λ˜λŠ” 'μ‚¬μš©λ˜λŠ” 객체' ν΄λž˜μŠ€κ°€ μž‘μ„±λœ μƒνƒœ
  • μ™ΈλΆ€λ‘œλΆ€ν„° μ£Όμž…μ΄λž€ 'μ‚¬μš©ν•˜λŠ” 객체' 클래슀의 λ°–μ—μ„œ 'μ‚¬μš©λ˜λŠ” 객체' μΈμŠ€ν„΄μŠ€λ₯Ό μ£Όμž…ν•˜λŠ” 것

κΈ°μ‘΄μ—λŠ” μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜λŠ”λ° new ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν–ˆμ§€λ§Œ μΈμŠ€ν„΄μŠ€ 생성과 같은 μž‘μ—…μ„ ν”„λ ˆμž„μ›Œν¬μ— 맑길 수 있고 κ·Έ 역할을 ν•  수 μžˆλ„λ‘ κΈ°λŠ₯을 μˆ˜ν–‰ν•˜λŠ” 것 -> 'DI μ»¨ν…Œμ΄λ„ˆ'


DI μ»¨ν…Œμ΄λ„ˆμ—κ²Œ μΈμŠ€ν„΄μŠ€ 생성을 μœ„ν•΄ μ§€μΌœμ•Όν•˜λŠ” 닀섯가지 κ·œμΉ™

DIμ»¨ν„°μ΄λ„ˆμ— μΈμŠ€ν„΄μŠ€ 생성을 맑기고 λ‹€μŒμ˜ κ·œμΉ™μ„ μ§€ν‚€λŠ” κ²ƒμœΌλ‘œ 'μ‚¬μš©ν•˜λŠ” 객체' 클래슀λ₯Ό μ „ν˜€ μˆ˜μ •ν•  수 μ—†κ²Œλ” λ§Œλ“€ 수 μžˆλ‹€.

  • κ·œμΉ™ 1. μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ΄μš©ν•˜μ—¬ μ˜μ‘΄μ„±μ„ λ§Œλ“ λ‹€.(=μ˜μ‘΄ν•˜λŠ” 뢀뢄에 μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ΄μš©ν•œλ‹€λŠ” 것)
  • κ·œμΉ™ 2. μΈμŠ€ν„΄μŠ€λ₯Ό λͺ…μ‹œμ μœΌλ‘œ μƒμ„±ν•˜μ§€ μ•ŠλŠ”λ‹€.(=μΈμŠ€ν„΄μŠ€ 생성에 new ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ§€ μ•ŠλŠ”λ‹€λŠ” 것)
  • κ·œμΉ™ 3. μ–΄λ…Έν…Œμ΄μ…˜μ„ ν΄λž˜μŠ€μ— λΆ€μ—¬ν•œλ‹€.
  • κ·œμΉ™ 4. μŠ€ν”„λ§ ν”„λ ˆμž„μ›Œν¬μ—μ„œ μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•œλ‹€.
    (= μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜λ €λŠ” ν΄λž˜μŠ€μ— μΈμŠ€ν„΄μŠ€ 생성 μ–΄λ…Έν…Œμ΄μ…˜μ„ λΆ€μ—¬ν•œλ‹€λŠ” 것. 즉 @Component μ–΄λ…Έν…Œμ΄μ…˜μ„ λΆ€μ—¬)
  • κ·œμΉ™ 5. μΈμŠ€ν„΄μŠ€λ₯Ό μ΄μš©ν•˜κ³  싢은 곳에 μ–΄λ…Έν…Œμ΄μ…˜μ„ λΆ€μ—¬ν•œλ‹€.(=μŠ€ν”„λ§ ν”„λ ˆμž„μ›Œν¬μ— μ˜ν•΄ μƒμ„±λœ μΈμŠ€ν„΄μŠ€λ₯Ό μ΄μš©ν•˜λŠ” ν΄λž˜μŠ€μ— μ°Έμ‘°λ₯Ό λ°›λŠ” ν•„λ“œλ₯Ό μ„ μ–Έν•˜κ³  ν•„λ“œμ— @Autowiredμ–΄λ…Έν…Œμ΄μ…˜μ„ λΆ€μ—¬)

μŠ€ν”„λ§λΆ€νŠΈ 핡심 κ°€μ΄λ“œμ—μ„œ λ§ν•˜λŠ” μ˜μ‘΄μ„±μ„ μ£Όμž…ν•˜λŠ” 방법

  • μƒμ„±μžλ₯Ό ν†΅ν•œ μ˜μ‘΄μ„± μ£Όμž…
  • ν•„λ“œ 객체 선언을 ν†΅ν•œ μ˜μ‘΄μ„± μ£Όμž…
  • setter λ©”μ„œλ“œλ₯Ό ν†΅ν•œ μ˜μ‘΄μ„± μ£Όμž…

πŸ“ŒμΈμŠ€ν„΄μŠ€ 생성 μ–΄λ…Έν…Œμ΄μ…˜

μ–΄λ…Έν…Œμ΄μ…˜κ°œμš”
@ControllerμΈμŠ€ν„΄μŠ€ 생성 μ§€μ‹œ. μŠ€ν”„λ§ MVCλ₯Ό μ΄μš©ν•  λ•Œ μ»¨νŠΈλ‘€λŸ¬μ— λΆ€μ—¬
@ServiceμΈμŠ€ν„΄μŠ€ 생성 μ§€μ‹œ. νŠΈλžœμž­μ…© 경계가 λ˜λŠ” 도메인(μ„œλΉ„μŠ€) κΈ°λŠ₯에 λΆ€μ—¬
@RepositoryμΈμŠ€ν„΄μŠ€ 생성 μ§€μ‹œ. λ°μ΄ν„°λ² μ΄μŠ€ μ•‘μ„ΈμŠ€(리포지토리) κΈ°λŠ₯에 λΆ€μ—¬ λΆ€μ—¬
@ComponentμΈμŠ€ν„΄μŠ€ 생성 μ§€μ‹œ. μœ„ μš©λ„ μ΄μ™Έμ˜ ν΄λž˜μŠ€μ— λΆ€μ—¬

ReferenceπŸ“š

  • μŠ€ν”„λ§ ν”„λ ˆμž„μ›Œν¬ 첫걸음 - ν›„λ£¨λ„€μŠ€ ν‚€λ…Έμ‹œνƒ€ λ§ˆμ‚¬μ•„ν‚€ -
  • μŠ€ν”„λ§λΆ€νŠΈ 핡심 κ°€μ΄λ“œ - μž₯μ •μš° -
profile
천천히, κΎΈμ€€νžˆ, 그리고 λκΉŒμ§€

0개의 λŒ“κΈ€