04. IoC_DI

💡 제어의 역전(IoC) 이란?

객체의 생성과 생명주기를 컨테이너가 담당한다는 개념이다. 즉 프로그램의 흐름을 개발자가 아닌 프레임워크가 관리한다. (개발의 복잡성이 줄어든다.)

💡 의존성 주입(DI) 이란?

IoC의 한 형태로, 객체 간의 의존성을 외부에서 주입하는 방식이다. (코드의 재사용성과 모듈의 독립성을 높인다) 의존성 주입에는 3가지 방법(생성자 주입, setter 주입, 자동 주입) 이 있다.

  🍙 실습을 위한 주먹밥 클래스 🍙

       (하단에 getter setter 메소드 있음)

1️⃣  생성자 주입

✔️ XML 사용

  1. constructor-arg 태그 사용
  2. value 에 값을, type 에 자료형을 입력한다. (기본 자료형은 String 이다.)
<bean class="beans.Jumeokbap" id="jumeokbap2">
	<constructor-arg value="1" type="int"/>
	<constructor-arg value="30초만 데워주세요"/>
</bean>

✔️ JAVA 사용

  1. 생성자 호출할 때와 동일한 방식으로 값을 주입한다.
	@Bean
	public Jumeokbap jumeokbap2() {
		Jumeokbap j = new Jumeokbap(1, "30초만 데워주세요");
		return j;
	}

2️⃣  setter 주입

✔️ XML 사용

  1. property 태그 사용
  2. name 에 변수명을, value 에 값을 입력한다.
<bean class="beans.Jumeokbap" id="jumeokbap3">
	<property name="orderCnt" value="1" />
	<property name="message" value="30초만 데워주세요" />
</bean>

✔️ JAVA 사용

  1. setter 메소드를 활용하여 주입한다.
	@Bean
	public Jumeokbap jumoJumeokbap3() {
		Jumeokbap j = new Jumeokbap();
		j.setOrderCnt(1);
		j.setMessage("30초만 데워주세요");
		return j;
	}

3️⃣  자동 주입

autowire 기능을 사용하면 스프링에서 연관관계를 찾아서 자동으로 의존관계를 주입해준다. 본 실습에서는 주먹밥 클래스의 필드 중에서 객체 타입인 cart 에 자동 주입으로 의존관계를 설정해보자.

🌱  “byName”

✔️ XML 사용

  1. 자동주입 하고자 하는 객체(Cart) 의 Bean 을 등록한다. 이 때 id는 주입받을 클래스에 설정해둔 변수명과 동일하게 설정해야 한다.

  2. cart 객체를 주입할 주먹밥 Bean에 autowire 속성을 사용한다.

  3. autowire = “byName” 속성을 사용하면 등록된 Bean 중에서 변수명이 동일한 Bean 을 찾아 자동으로 주입해준다.

<bean class="beans.Cart" id="cart" />
<bean class="beans.Jumeokbap" id="jumeokbap4" autowire="byName"/>

🌱  “byType”

✔️ XML 사용

  1. byName 과 마찬가지로 자동주입 하고자 하는 객체(Cart) 의 Bean 을 먼저 등록한다.

  2. cart 객체를 주입할 주먹밥 Bean 에 autowire 속성을 사용한다.

  3. autowire = “byType” 속성을 사용하면 등록된 Bean 중에서 같은 타입(실습에서 사용한 자료형은 Cart 객체이다) 을 찾아서 자동으로 주입해준다.

<bean class="beans.Cart" id="cart" />
<bean class="beans.Jumeokbap" id="jumeokbap5" autowire="byType" />

🌱  @Autowired

✔️ JAVA 사용

  1. @Configuration 파일에 자동주입 하고자 하는 객체 (Cart) 와 주입 받을 객체 (Pudding) 을 둘 다 등록해준다.

  2. 자동 주입 받을 객체(Pudding) 에서, 해당 변수에 @Autowired 어노테이션을 붙인다.

(1)
@Configuration
public class BeanClass {

	@Bean
	public Cart cart() {
		return new Cart();
	}

	@Bean
	public Pudding pudding() {
		return new Pudding();
	}

}

(2)
public class Pudding extends Cart{

	//필드
	private int orderCnt;
	private String message;
	@Autowired
	private Cart cart;

}

✔️ 필드에 자동 주입 받을 객체가 여러 개라면 ?

  • @Qualifier 어노테이션을 붙이면 됩니다.
(1)
@Configuration
public class BeanClass {

	//@Qualifier 어노테이션이 붙은 변수가 있으면 Bean 을 선언할 때의 메소드명을 name 과 일치시켜야 한다.
	@Bean
	public Cart obj1() {
		return new Cart();
	}

	@Bean
	public Cart obj2() {
		return new Cart();
	}

	@Bean
	public Pudding pudding() {
		return new Pudding();
	}

}

(2)
public class Pudding extends Cart{

	//필드
	private int orderCnt;
	private String message;

	//같은 객체가 여러 개 선언되어 있어 어떤 객체에 자동 주입을 해야 하는지 구별할 수 없음. 이럴 때는 변수별 이름을 따로 설정해주면 된다.
	@Autowired
	@Qualifier("obj1")
	private Cart cart;

	@Aurowired
	@Qualifier("obj2")
	private Cart cart2;

}

🌱  @Resource(name=””)

✔️ JAVA 사용

Autowired 는 같은 타입을 가진 변수에 값을 주입시켜주지만 Resource 는 같은 이름을 가진 변수에 값을 주입시켜준다.

	@Resource(name = "cart")
	private Cart cart;