본문 바로가기

웹 기술 쌈싸먹기/Spring

[Spring] DI(의존성 주입) 란?

DI(의존성 주입)

 

1) 강한 결합의 문제점

  • 강한결합 예제
    1. Contoller1 이 Service1 객체를 생성하여 사용
      public class Controller1 { private final Service1 service1; public Controller1() { this.service1 = new Service1(); } }
    2. Service1 이 Repostiroy1 객체를 생성하여 사용
      public class Service1 {
      	private final Repository1 repository1;
      
      	public Service1() {
      		this.repository1 = new Repository1();
      	}
      }
    3. Repostiroy1 객체 선언
      public class Repository1 { ... }
    4. Repository1 객체 생성 시 DB 접속 id, pw 를 받아서 DB 접속 시 사용
      public class Repository1 {
      
      	public Repository1(String id, String pw) {
          // DB 연결
          Connection connection = DriverManager.getConnection("jdbc:h2:mem:springcoredb", id, pw);
        }
      }

 

  • 강한 결합의 문제점
    • Controller 5 개가 각각 Service1 을 생성하여 사용 중
    • Repository1 생성자 변경에 의해... 모든 Contoller 와 모든 Service 의 코드 변경이 필요

 

2) 강한결합 해결방법

👉 그렇다면 "강한 결합"을 해결할 방법이 없나요?
-> 각 객체에 대한 객체 생성은 딱 1번만~~~ 생성된 객체를 모든 곳에서 재사용~~~

 

  • 강한결합 해결방법 예제
    public class Repository1 { ... }
    
    // 객체 생성
    Repository1 repository1 = new Repository1();

 

  1. Repository1 클래스 선언 및 객체 생성 → repository1
  2. Service1 클래스 선언 및 객체 생성 (repostiroy1 사용) → service1
    Class Service1 {
    	private final Repository1 repitory1;
    
    	// repository1 객체 사용
    	public Service1(Repository1 repository1) {
    		this.repository1 = new Repository1();
    		this.repository1 = repository1;
    	}
    }
    
    // 객체 생성
    Service1 service1 = new Service1(repository1);​
  3. Contoller1 선언 ( service1 사용)
    Class Controller1 {
    	private final Service1 service1;
    
    	// service1 객체 사용
    	public Controller1(Service1 service1) {
    		this.service1 = new Service1();
    		this.service1 = service1;
    	}
    }​
  4. Repository1 객체 생성 시 DB 접속 id, pw 를 받아서 DB 접속 시 사용
    public class Repository1 {
    
    	public Repository1(String id, String pw) {
        // DB 연결
        Connection connection = DriverManager.getConnection("jdbc:h2:mem:springcoredb", id, pw);
      }
    }
    
    // 객체 생성
    String id = "sa";
    String pw = "";
    Repository1 repository1 = new Repository1(id, pw);​

 

👉 개선결과

⇒ Repository1 생성자 변경은 이제 누구에게도 피해(?) 를 주지 않음
⇒ Service1 생성자가 변경되면? 모든 Contoller → Controller 변경 필요 X

결론적으로, 강한 결합 ⇒ 느슨한 결합으로 만들어야한다!!!

 

3) DI (의존성 주입)의 이해

👉 제어의 역전(IoC: Inversion of Control)
⇒ 프로그램의 제어 흐름이 뒤바뀜
  • 일반적: 사용자가 자신이 필요한 객체를 생성해서 사용
  • IoC(제어의 역전)
    • 용도에 맞게 필요한 객체를 그냥 가져다 사용
      • "DI (Dependency Injection)" 혹은 한국말로 "의존성 주입"이라고 부릅니다.
    • 사용할 객체가 어떻게 만들어졌는지는 알 필요 없음
    • 실생활 예제) 가위의 용도별 사용
      1. 음식을 자를 때 필요한 가위는? → 부엌가위(생성되어 있는 객체)
      2. 무늬를 내며 자를 때 필요한 가위는? → 핑킹가위(생성되어 있는 객체)
      3. 정원의 나무를 다듬을 때 필요한 가위는? → 전지가위(생성되어 있는 객체)