ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 제어의 역전과 의존 주입(Ioc / DI)
    spring boot 2023. 4. 10. 12:51
    학습목표
    Ioc 개념에 대해 이해
    DI 개념에 대해 이해

     

    Ioc(Inversion of Control, Ioc)
    1. 스프링에서는 일반적으로 Java 객체를 new로 생성하여 개발자가 관리하는 것이 아닌
    spring Container 에게 모두 맡긴다.
    2. 개발자에게서 실행에 제어권을 프레임워크로 권한이 넘어 갔다라는 의미로 제어의 역전이라고 한다.
    3. Ioc의 대상은 싱글톤으로 관리 됩니다.

     

    DI(Dependency Injection, DI) 의존성 주입
    1. 필요할때 spring container 에서 가져와서 사용한다.

    - 의존성으로 부터 격리 시켜 코드 테스트가 용이하다. 루즈커플링이 가능하다.
    - 코드를 확장하거나 변경할 때 영향을 최소화 한다. (추상화)
    - 어떠한 객체를 작동시킬 때 클래스가 2개 있는데 모든 클래스를 한곳에 넣어버리면 수정할때
    다 바꿔야 한다. 이럴때 루즈하게 커플링하면 수정이 용이하다.
     IoC는 소프트웨어 디자인 패턴 중 하나로, 컴퓨터 프로그램의 제어 흐름이 뒤바뀌는 것을 의미합니다. 일반적인 프로그램의 제어 흐름은 개발자가 코드를 작성하여 제어합니다. 하지만 IoC를 사용하면, 제어 흐름의 일부 또는 전부를 프레임워크가 제어하게 됩니다. 이를 통해 프로그램의 유연성과 재사용성이 높아질 수 있습니다.

    DI는 IoC의 한 형태로, 클래스가 자신이 사용할 객체를 직접 생성하지 않고, 외부에서 이를 주입받아 사용하는 것을 의미합니다. DI를 사용하면 클래스 간의 의존성을 줄이고, 클래스의 재사용성과 유연성을 높일 수 있습니다.

    즉, IoC는 프로그램의 제어 흐름을 뒤바꾸는 개념이고, DI는 클래스가 의존하는 객체를 외부에서 주입받아 사용하는 방식을 말합니다. DI는 IoC를 구현하는 방법 중 하나입니다.

    따라서, IoC와 DI는 밀접한 관련이 있지만, 서로 다른 개념입니다. IoC는 프로그램의 제어 흐름을 뒤바꾸는 개념이고, DI는 클래스가 의존하는 객체를 외부에서 주입받아 사용하는 방식을 말합니다.


    * Gof의 디자인 패턴 (디자인 패턴 책중에 유명한 책) 참조

     

    스프링 컨테이너 녀석이 자동으로 Ioc 해준다.

    만약 Api controller를 만들면 스프링 컨테이너에 BEAN으로 올라간다.

    서블릿은 외부적으로 가지고 있지만 왠만하면 건드리지 않고 스프링 컨테이너만 건드는게 목적이다.

     

    Ioc <- 스프링 컨테이너에 싱글톤 패턴으로 올라간다 - BEAN 객체

    @RestController

     

    DI

    - 하고싶은 인코더 클래스를 주입만 하면 그 구현 클래스에 맞게 기능을 처리 할 수 있다.

     

    1.인터페이스 선언

    package ch02;
    
    public interface IEncoder {
    	// URL 인코딩, Base64 인코딩
    	// 문자형 데이터 (바이터리 타입을 문자열로 Base64 형태)
    	String encode(String message);
    }

     

    2. 구현 클래스 만들기

    package ch02;
    
    import java.util.Base64;
    
    public class Base64Encoder implements IEncoder {
    
    	@Override
    	public String encode(String message) {
    		// 인코딩 -> Base64 형식으로 처리
    		String resultEncode = 
    				Base64.getEncoder().encodeToString(message.getBytes());
    		return resultEncode;
    	}
    
    }
    package ch02;
    
    import java.io.UnsupportedEncodingException;
    import java.net.URLEncoder;
    
    public class UrlEncoder implements IEncoder{
    	
    	
    	
    	@Override
    	public String encode(String message) {
    		try {
    			return URLEncoder.encode(message,"UTF-8");
    		} catch (UnsupportedEncodingException e) {
    			e.printStackTrace();
    			return null;
    		}
    	}
    
    }
    package ch02;
    
    public class MyEncoder implements IEncoder {
    
    	@Override
    	public String encode(String message) {
    		String resultEncode = ">>>"+ message + "<<<";
    		return resultEncode;
    	}
    
    	
    }

     

    3. 중간 클래스 만들기

    package ch02;
    
    public class Encoder {
    	
    	private IEncoder iEncoder;
    	
    	//DI 의존 주입 설정 + 전략 패턴
    	public Encoder(IEncoder iEncoder) {
    		this.iEncoder = iEncoder;
    	}
    	
    	// 기능
    	public String encode(String message) {
    		return iEncoder.encode(message);
    	}
    }

     

    package ch02;
    
    public class MainTest1 {
    
    	public static void main(String[] args) {
    		
    		// 중간 클래스 만들었음 !
    		String url = "www.naver.com/books/id?=100";
    		
    		// IEncoder 생성자 타입 -> 의존 주입 설계 
    		// Base64Encoder <- IEncoder 타입으로 바라볼 수 있다.
    		// URIEncoder <- IEncoder 타입으로 바라볼 수 있다.
    		
    		// 하고싶은 인코더 클래스를 주입만 하면 그 구현 클래스에 맞게
    		// 기능을 처리할 수 있다.
    		Encoder encoder = new Encoder(new UrlEncoder());
    		String result1 = encoder.encode(url);
    		System.out.println("result1 : " +result1);
    		
    		Encoder encoder2 = new Encoder(new Base64Encoder());
    		String result2 = encoder2.encode(url);
    		System.out.println("result2 : " + result2);
    		
    		Encoder encoder3 = new Encoder(new MyEncoder());
    		String result3 = encoder3.encode(url);
    		System.out.println("result3 : " + result3);
    	}
    
    }

     

     

    setter 메서드 이용

    	// setter 까지 만들면 전략 패턴 완성
    	public void setiEncoder(IEncoder iEncoder) {
    		this.iEncoder = iEncoder;
    	}

     

    	encoder.setiEncoder(new Base64Encoder());
    		System.out.println(encoder.encode("반가워"));

     

     

    'spring boot' 카테고리의 다른 글

    AOP 개념 살펴보기  (0) 2023.04.10
    Maven이란?  (0) 2023.04.10
    스프링 핵심  (0) 2023.04.10
    Response 와 MIME TYPE 에 이해  (0) 2023.04.10
    DELETE 방식에 이해 및 실습  (0) 2023.04.10
Designed by Tistory.