Christmas Pikachu IoC - Inversion Of Control
개발일지/스프링

IoC - Inversion Of Control

ZI_CO 2022. 12. 4.

 IoC의 개념

 

IoC(제어권의 역전)이란, 객체의 생성, 생명주기의 관리까지 모든 객체에 대한 제어권이 바뀌었다는 것을 의미한다.

 

컴퓨넌트 의존관계 결정 (Component dependency resolution), 설정(configuration) 및 생명주기(lifecycle)를 해결하기 위한 디자인 패턴(Design Pattern)

 

1. 스프링에서는 일반적으로 java 객체를 new로 생성하여

개발자가 관리하는 것보다 Spring Container가 객체 생성 및 관리를 한다.

 

2. 개발자에서 실행의 제어권이 프레임워크로 권한이 넘어갔다라는 의미로

제어의 역전이라고 한다.

 

3. Spring Container가 생성한 객체를 Bean(빈) 이라고 부르고

아주 많은 객체들을 생성하고 관리하기 때문에, 이렇게 실행되는 객체들을 Beans(빈즈) 라고 한다.

 

 

스프링 빈은 스프링 컨테이너에 의해 관리되는 자바객체를 의미한다.

개발자 : 스프링 컨테이너에 너가 객체를 생성해서 관리하거라!

스프링 : 알았어! 내가 관리하는 컨테이너에 넣고 "싱글톤"으로 관리할게

나중에 너가 필요하다면 DI를 통해 가져가서 사용해!

 

 

* 스프링 컨테이너가 객체 생성 시켜주는 어노테이션

@Component (" ")

@Qualifier

(IoC가 되면서 DI의 매개변수가 여러 개라 어떤 것을 객체로 생성할지 모를 때,

지정해주면 해당 객체로 생성된다.)

 

 

IEncoder (인터페이스)

package com.example.ioc;

public interface IEncoder {
	String encode(String msg);
}

 

 

MyEncoder

package com.example.ioc;

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

@Component
public class MyEncoder {
	
	private IEncoder iEncoder;

	public MyEncoder(@Qualifier("MyUrlEncoder") IEncoder iEncoder) {
		this.iEncoder = iEncoder;
	}
	
	public void setIEncoder(IEncoder iEncoder) {
		this.iEncoder = iEncoder;
	}
	
	// 기능 encoding
	public String encode(String msg) {
		return iEncoder.encode(msg);
	} 
	
}

 

 

 

MyUrlEncoder

package com.example.ioc;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import org.springframework.stereotype.Component;

@Component("MyUrlEncoder")
public class UrlEncoder implements IEncoder{

	@Override
	public String encode(String msg) {
		String result = null;
		try {
			result  = URLEncoder.encode(msg, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		
		return result;
	}

}
 

 

 

MyBase64Encoder

package com.example.ioc;
import java.util.Base64;
import org.springframework.stereotype.Component;

@Component 
public class MyBase64Encoder implements IEncoder {

	@Override
	public String encode(String msg) {
		return Base64.getEncoder().encodeToString(msg.getBytes());
	}
}

 

 

 

ApplicationContextProvider

ApplicationContext는 해당 애플리케이션에 대한 구성정보를 제공하는 인터페이스이다.

애플리케이션에 대한 구성정보라는 것은 등록한 Bean에 대한 정보를 포함하는 것으로,

특정 타입의 Bean의 리스트를 가져온다거나 하는 등

Bean의 정보들을를 가져올 수 있다.

package com.example.ioc;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class ApplicationContextProvider implements ApplicationContextAware {

	private static ApplicationContext context;

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) 
    throws BeansException {
		context = applicationContext;
	}
	
	// 기능 - ApplicationContext 가져 갈 수 있게 처리
	public static ApplicationContext getContext () {
		return context;
	}
	
	

}

 

 

 

* SpringIocApplication

DI가 여러개인 IoC에게 @Qualifier로 지정 시켜 객체 생성을 했었다.

다른 객체로 바꾸고 싶다면 ? ? -> set 메서드를 만들어준 후 사용한다.

IoC 사용 방법 : UrlEncoder urlEncoder = context.getBean(UrlEncoder.class);
package com.example.ioc;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

@SpringBootApplication
public class SpringIocApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringIocApplication.class, args);
		
		// 개발자가 직접생성 : MyBase64Encoder base64Encoder = new MyBase64Encoder();
		
		ApplicationContext context = ApplicationContextProvider.getContext();
		String myUrl = "www.naver.com/?q=우리 이길까 ? ? ?";
		//생성 IoC
		MyBase64Encoder base64Encoder = context.getBean(MyBase64Encoder.class);
		UrlEncoder urlEncoder = context.getBean(UrlEncoder.class);
		MyEncoder encoder = context.getBean(MyEncoder.class);

		//@Qualifier 되어있는 urlEncoder의 결과를 도출
		String result = encoder.encode(myUrl);
		System.out.println(result);

		// 변경처리--> base64Encoder의 결과를 도출
		encoder.setIEncoder(base64Encoder);
		String result = encoder.encode(myUrl);
		System.out.println(result);
	}

}

댓글