본문 바로가기
spring

[spring] DI, IOC란?

by 콧등치기국수 2021. 10. 14.

1. DI (Dependecy Injection)

의존 관계 주입기능으로 사용하는 객체를 직접 생성하여 만들지 않고, 외부에서 생성한 후 주입시켜주는 방식이다.

컨테이너가 빈의 설정 정보를 읽어와 자동으로 해당 객체에 연결하는 것을 의미한다.

이렇게 의존성을 주입받게 되면 이후 해당 객체를 수정해야 할 상황이 발생했을 때 소스코드의 수정을 최소화할 수 있다. DI를 통해서 각 모듈 간의 결합도를 낮출 수 있다.

 

- 방법 1 (의존성 주입 X)

: A객체가 B , C 객체를 New생성자를 통해서 직접 생성하는 방법이다.

아래와 같이 BoardServiceImpl 클래스에서 BoardDao객체를 직접 생성하는 방식이다.

BoardServiceImpl 클래스를 만들려면 BoardDao 클래스를 필요로 하는데, 이것을 클래스가 의존성을 가지는 것으로 본다. BoardDao클래스가 수정되었을 때, BoardServiceImpl도 함께 수정해야하는 문제가 발생한다. 따라서 결합도가 높다.   

객체 내부에서 다른 객체를 생성하는 것은 강한 결합도를 가지는 구조이다.A 클래스 내부에서 B 라는 객체를 직접 생성하고 있다면, B 객체를 C 객체로 바꾸고 싶은 경우에 A 클래스도 수정해야 하는 방식이기 때문에 강한 결합이다.

 

- 방법 2 (의존성 주입 O)

A객체에서 B, C객체를 사용(의존)할 때, A객체에서 직접 생성하지 않고, 외부(IOC컨테이너)에서 생성된 B,C객체를 주입시켜 setter 혹은 생성자를 통해 사용하는 방식이다.

1-1. Spring DI 종류

📌 Spring Bean Configuration File을 생성하여 xml 파일을 만들어서 객체(Bean)를 생성하고 기능을 구현한다.

 

1) Setter 메소드를 통한 의존성 주입 

setter 메서드로 의존 객체를 주입받는 방식

 

📌 Setter 메소드를 통해 의존관계가 있는 Bean을 주입하려면 <property> 태그를 사용한다.

<bean id=“student"class=“com.kh.spring.person.model.vo.Student“>
	<property name=“name” value=“홍길동”/>
	<property name=“wallet” ref=“money”/>
</bean>

<bean id=“money” class=“com.kh.spring.wallet.model.vo.Wallet” />

- id : 빈 객체를 구분할 때 사용할 이름

- class :  빈 객체를 생성할 때 사용할 클래스

 

- name 속성 : 클래스에서 선언한 필드 변수의 이름

- value 속성 : 단순값또는Bean이아닌객체를주입할때사용

- ref 속성 : Bean 이름을이용해주입할Bean을찾음

 

위 xml설정 코드는 다음과 같은 자바코드를 실행하는 것과 같을 것 같아 적어보았다.

(이 부분은 내가 공부하면서 이해한 내용을 토대로 적은 것이므로 틀렸을 수도 있다.)

public String getName() {
    return userId;
}

public void setName(String userId) {
    this.userId = userId;
}

public Wallet getWallet() {
    return wallet;
}

public void setWallet(Wallet wallet) {
    this.wallet = wallet;
}

 

2) 생성자를 통한 의존성 주입

생성자를 통해서 의존 객체를 주입받는 방식이다.

 

📌 Constructor를통해의존관계가있는Bean을주입하려면<constructor-arg> 태그를사용한다.

<constructor-arg> : 생성자를 이용해서 의존 객체를 주입할 때 사용한다.

- 생성자에 전달할 객체가 2개이다.

- 이름이 money인 다른 bean객체를 생성해서, 생성자에 전달한다는 의미이다.

<bean id=“student"class=“com.kh.spring.person.model.vo.Student“>
	<constructor-arg index=“0” value=“홍길동“/>
	<constructor-argindex=“1”ref=“money”/>
</bean>

<bean id=“money” class=“com.kh.spring.wallet.model.vo.Wallet” />

- id : 빈 객체를 구분할 때 사용할 이름

- class :  빈 객체를 생성할 때 사용할 클래스

 

- Constructor 주입방식은 생성자의 파라미터를 이용하기 때문에 한 번에 여러 개의 객체주입 가능
- 필드 선언 순서에 따라 index 속성을 통해서도 접근이 가능하다.

 

위 xml설정 코드는 다음과 같은 자바코드를 실행하는 것과 같을 것 같아 적어보았다.

(이 부분은 내가 공부하면서 이해한 내용을 토대로 적은 것이므로 틀렸을 수도 있다.)

Wallet money = new Wallet();
Student student = new Student("홍길동", money);

 

3) 메소드를 통한 의존성 주입

 

 

2. IOC 제어반전 (Inversion of Control)

컨트롤의 제어권이 개발자가 아니라 프레임워크에 있다는 뜻으로, 객체의 생성부터 모든 생명주기의 관리까지 프레임워크가 주도하고 있다.

프로그램을 구동하는데 필요한 객체에 대한 생성, 변경 등의 관리를 프로그램을 개발하는 사람이 아닌 프로그램을 구동하는 컨테이너에서 직접 관리하는 것을 말한다.

객체의 의존성을 역전시켜서 객체 간의 결합도를 줄이고 유연한 코드를 작성할 수 있게 하여 가독성 및 코드 중복, 유지보수를 편하게 할 수 있게 한다.

 

2-1. IoC컨테이너

IoC컨테이너는 객체의 생성과 관계설정(의존성), 사용, 소멸 등의 작업을 관리해준다.

Spring Container, IoC Container, Bean Container 로도 불린다.

 

IoC Container는 Bean을 저장한다고 하여, BeanFactory 라고도 불린다. BeanFactory는 하나의 인터페이스이며, Application Context는 BeanFactory의 구현체를 상속받고 있는 인터페이스이다.

Bean Factory는 Bean을 등록, 생성, 조회, 반환하는 기능을 담당한다.

* ApplicationContext : BeanFactory를 확장한 IoC컨테이너이다. Bean을 등록하고 관리하는 기능은 BeanFactory와 동일하지만 스프링이 제공하는 각종 부가 서비스를 추가로 제공한다.

 

 

3. Bean이란?

Bean은 스프링 IOC컨테이너가 관리하는 객체(class)이다. (스프링에서는 객체를 Bean이라고 부른다고 이해하면 쉬울 것 같다.) 스프링이 직접 생성과 제어를 담당하는 객체이다.

 

* Bean으로 등록되었을 때의 장점

    1. 스프링 IOC컨테이너에 등록된 Bean 들은 의존성 관리가 수월해진다.

    2. 스프링 IOC컨테이너에 등록된 Bean들은 싱글톤의 형태이다.

 

스프링이 모든 의존성 객체를 스프링이 실행될 때 다 만들어주고, 필요한 곳에 주입시켜줌으로써 Bean들은 싱글턴 패턴의 특징을 가지며, 제어의 흐름을 사용자가 컨트롤하는 것이 아니라 스프링에게 맡겨서 작업을 처리하게 되는 것이다.

 

 

 

(본격적인 spring 수업 전 개인공부로 적은 것이므로 틀린 내용이 있을 수도 있습니다)

 

 

참고 및 출처 : kh정보교육원 교육자료

https://velog.io/@gillog/Spring-DIDependency-Injection

https://devlog-wjdrbs96.tistory.com/165

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=sksk3479&logNo=221177545396 

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=sksk3479&logNo=221177545396 

https://atoz-develop.tistory.com/entry/Spring-%EC%8A%A4%ED%94%84%EB%A7%81-XML-%EC%84%A4%EC%A0%95-%ED%8C%8C%EC%9D%BC-%EC%9E%91%EC%84%B1-%EB%B0%A9%EB%B2%95-%EC%A0%95%EB%A6%AC

'spring' 카테고리의 다른 글

[spring] DispatcherServlet  (0) 2021.10.23
[spring] Context란?  (0) 2021.10.20
[spring] annotation 이용한 DI  (0) 2021.10.20
[spring] 느슨한 결합력과 인터페이스(DI 이해에 도움)  (0) 2021.10.15
[spring] AOP  (0) 2021.10.15