Spring

[Spring] Inversion of Control (IoC)

Jesse 2022. 1. 11. 01:32

Inversion of Control(IoC)이란?

직역을 하자면 제어의 역전이다. 하지만, 이렇게 얘기하면 전혀 와 닿지가 않는다. 

제어가 역전 되었다고 하는데 제어의 대상은 무엇인가 누구에서 누구로 역전 되었다는걸까

기존에는 객체를 생성하고 관리하는 걸 개발자가 직접 코드로 했다면,

제어의 역전을 적용하면 이런 일들을 개발자가 아닌 프레임워크가 하게 하는 것이다.

즉, 객체 생성과 관리의 주도권이 개발자가 아닌 프레임워크에게 있다는 뜻이다.

그럼 이게 왜 필요한지에 대해서는 직접 코드를 작성해보면 알수 있다.

선생님이라는 클래스를 만들어 봤다.

선생님은 당연히 여러 업무를 하시겠지만 예시용으로 가르치는 일만 하는걸로 하자.

 

예시 (IoC 적용 안 했을때)

선생님은 당연히 수학, 과학, 체육 등등 다양한 선생님이 있을수 있으니

package com.luv2code.springdemo;

public interface Teacher {

	public String teach();
	
}

Teacher라는 인터페이스를 먼저 만들어서 특정 과목 선생님 클래스들은 Teacher 인터페이스를 상속 받도록 했다.

package com.luv2code.springdemo;

public class MathTeacher implements Teacher {

	@Override
	public String teach() {
		return "수학 수업을 시작 하겠습니다!!!";
	}

}

수학 선생님

package com.luv2code.springdemo;

public class EnglishTeacher implements Teacher {

	@Override
	public String teach() {
		return "Let's start the lecture!!!";
	}

}

영어 선생님

package com.luv2code.springdemo;

public class MyApp {

	public static void main(String[] args) {

		// 객체 생성
		Teacher myTeacher = new MathTeacher();
		
		// 생성된 객체 사용
		System.out.println(myTeacher.teach());		
	}

}

main 메소드에서 MathTeacher 객체를 생성하고 teach 라는 함수를 부르도록 하였다.

자 그럼 IoC를 적용하면 도대체 어떻게 저 MathTeacher라는 객체를 생성하는 부분을 개발자가 아닌 프레임워크가 하게 끔 할수 있을까?

예시 (IoC 적용 했을때)

코드를 작성하기 전에 흐름을 보자면,

객체를 필요로 한다고 요청을 보내면 Object Factory는 요청한 객체를 Configuration 한다.

Configuration의 방법에는 총 3가지가 있다.

  • XML configuration file
  • Java Annotations
  • Java Source Code

아래 코드는 XML configuration file을 사용한 방식이다.

더보기

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- Define your beans here -->
    
  <bean id="myTeacher"
  class="com.luv2code.springdemo.MathTeacher">  
  </bean>

</beans>

applicationContext.xml 파일에 사용하고자 하는 객체를 등록한다.

bean id는 생성하는 객체의 변수명이고 어떤 class인지는 

 class="com.luv2code.springdemo.MathTeacher

이렇게 패키지 명이랑 붙여서 작성한다.

package com.luv2code.springdemo;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyApp {

	public static void main(String[] args) {

		// 스프링 configuration 파일을 불러온다
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
				
		// 스프링 컨테이너에서 해당 빈을 찾아서 불러온다
		Teacher myTeacher = context.getBean("myTeacher", Teacher.class);
		
		// 사용하려는 빈의 메소드를 부른다
		System.out.println(myTeacher.teach());
		
		// 불러온 스프링 configuration 파일을 닫는다
		context.close();
	}

}