각진 세상에 둥근 춤을 추자

[Spring] IoC&DI 본문

Spring

[Spring] IoC&DI

circle.j 2023. 1. 3. 01:28

1. IoC

  • IoC(Inversion of Control)는 객체의 생성, 생명주기의 관리까지  모든 객체에 대한 제어권이 바뀌었다는 것을 의미하는 제어의 역전
  • 일반적으로 사용자가 객체를 생성하는 대신 객체의 제어를 사용자가 아닌 객체의 생성과 관리를 수행하는 컨테이너(IoC Container)에 위임하는 형태를 말한다.
  • Spring은 Spring Container를 사용하며 객체의 생성, 초기화, 서비스, 소멸에 대한 생명주기를 관리하고 권한을 가진다.

 

 

 


 

2.  DI

 

DI(Dependency Injection) 의존성 주입이라 하고 IoC 개념을 프로그래밍적으로 구현하는 방법을 의미한다.

 

DI 유형: 의존 관계에 있는 Bean을 주입하는 방법 

(1) Setter Injection - setter 메서드를 통해 의존 관계에 있는 객체를 주입

(2) Constructor Injection - 생성자를 통해 의존 관계에 있는 객체를 주입

(3) Field Injection - Annotation(@Autowired)을 이용

 

@Autowired

스프링 DI(Dependency Injection)에서 사용되는 어노테이션

스프링에서 빈 인스턴스가 생성된 이후 @Autowired를 설정한 메서드가 자동으로 호출, 인스턴스가 자동으로 주입된다. 

 


 

3. IoC를 적용 - 스프링 컨테이너로 객체 주입

 

(1) LgTV.java

package kr.co.ch02.sub1;

import org.springframework.beans.factory.annotation.Autowired;

public class LgTV {
	
	@Autowired
	private Speaker spk;	
	// 멤버(참조 변수)로 선언 -> 현재 초기화 하지 않은 상태라 null임 -> application.xml에 bean 등록 & autowired 
	
	
	public void powerOn() {
		System.out.println("LgTV powerOn...");
	}
	public void powerOff() {
		System.out.println("LgTV powerOff...");
	}
	public void soundUp() {
		//System.out.println("LgTV soundUp...");
		spk.soundUp();
	}
	public void soundDown() {
		//System.out.println("LgTV soundDown...");
		spk.soundDown();
	}
}

 

(2) SamsungTV.java

package kr.co.ch02.sub1;

import org.springframework.beans.factory.annotation.Autowired;

public class SamsungTV {
	
	@Autowired
	private Speaker spk;	
	
	public void powerOn() {
		System.out.println("SamsungTV powerOn...");
	}
	public void powerOff() {
		System.out.println("SamsungTV powerOff...");
	}
	public void soundUp() {
		//System.out.println("SamsungTV soundUp...");
		spk.soundUp();
	}
	public void soundDown() {
		//System.out.println("SamsungTV soundDown...");
		spk.soundDown();
	}
}

 

(3) Speaker.java

package kr.co.ch02.sub1;

public class Speaker {

	public void soundUp() {
		System.out.println("Speaker soundUp...");
	}
	public void soundDown() {
		System.out.println("Speaker soundDown...");
	}
	
}

 

(4) IoCMain.java

package kr.co.ch02.sub1;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;


public class IoCMain {
	public static void main(String[] args) {

		// IoC 적용: 스프링 컨테이너로 객체 주입 (ctx: 스프링 컨테이너)
		ApplicationContext ctx = new GenericXmlApplicationContext("application.xml");
		
		LgTV lTv = ctx.getBean("ltv", LgTV.class);
		SamsungTV sTv =  ctx.getBean("stv", SamsungTV.class);
		
		lTv.powerOn();
		lTv.soundUp();
		
		sTv.powerOff();
		sTv.soundDown();
		
		
	}
}

 

 


 

4. DI를 통해 의존관계에 있는 Bean 주입하기

 

(1) CPU.java

package kr.co.ch02.sub2;

import org.springframework.stereotype.Component;

@Component
public class CPU {
	public void show() {
		System.out.println("CPU : intel i7");
	}
}

 

(2) HDD.java

package kr.co.ch02.sub2;

import org.springframework.stereotype.Component;

@Component
public class HDD {
	public void show() {
		System.out.println("HDD : 1TB");
	}
}

 

(3) RAM.java

package kr.co.ch02.sub2;

import org.springframework.stereotype.Component;

@Component
public class RAM {
	public void show() {
		System.out.println("RAM : 16GB");
	}
}

 

(4) Computer.java

package kr.co.ch02.sub2;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component(value = "com")
public class Computer {
	
	// DI 1번 방법: 생성자 (Constructor Injection)
	private CPU cpu;
	
	@Autowired
	public Computer(CPU cpu) {
		this.cpu = cpu;
	}
	
	// DI 2번 방법: 세터 인젝션
	private RAM ram;
	
	@Autowired
	public void setRam(RAM ram) {
		this.ram = ram;
	}
	
	// DI 3번 방법: 필드 인젝션 (주로 사용)
	@Autowired
	private HDD hdd;
	
	
	
	public void show() {
		cpu.show();
		ram.show();
		hdd.show();
	}
	
	
}

 

(5) Main.java

package kr.co.ch02.sub2;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;

public class Main {
	public static void main(String[] args) {
		
		ApplicationContext ctx = new GenericXmlApplicationContext("application.xml");
		
		Computer com = ctx.getBean("com", Computer.class);
		com.show();
	}
}