본문 바로가기

BE,FE(개발)/Java,Python (server)

면접 공부를 하다 DI를 공부하다.(Spring)

들어가기 전에..

백엔드 사람들의 오픈챗 방에서 좋은 정보를 얻고 정리 한번 합니다.

For Example,

MemoryStorage에 넣으면 메모리에 값이 들어갔다가 프로그램 꺼지면 지워질꺼구요
DBStorage를 넣으면 DB에 select, insert/update, delete가 되겠죠
이걸 프로그램을 만드는 시점이 아니라 config 등을 통해서 실행하는 시점에 넣을 수 있다면
컴파일 변경 없이 기능을 추가하거나 변경하는 효과를 볼 수 있습니다.

 

Summary, 아.. DI는 프로그램이 만드는 시점이 아니라 Config등을 통해(다른 곳에서 작동을 할 때) 트랜잭션이나 다른 클래스를 넣어주면 컴파일 변경 없이 기능을 추가하거나 변경 가능하구나~?

 

이제 알아보자.

 

스프링 DI(의존관계 주입) 이란 무엇인가요?

Dependency Injection 외부에서 두 객체 간의 관계를 결정해주는 디자인 패턴.

인터페이스를 사이에 둬서 클래스 레벨에서는 의존관계가 고정되지 않도록 하고, 런타임 시에 관계를 동적으로 주입.

의존성이랑 한 객체가 다른 객체를 상용할 때 의존성이 있다고 한다.

public class Store{
	private Pencil pencil;
}

Store 객체가 Pencil 객체를 사용하고 있는 경우 우리는 Store객체가 Pencil 객체에 의존성이 있다고 표현한다.

그리고 두 객체 간의 관계(의존성) 을 맺어주는 것을 의존성 주입이라고 하며 생성자 주입, 필드 주입, 수정자 주입 등 다양한 주입 방법이 있다. Spring 4부터는 생성자 주입을 강력히 권장

의존성 주입(Dependency Injection)이 필요한 이유

문제점이 있다.

  • 두 클래스 강하게 결합
  • 객체들 간 관계가 아니라 클래스 간 관계가 맺어짐.
public class Store{
	private Pencil pencil;
    public Store(){
    	this.pencil = new Pencil();
    }
}

여기서의 문제점은 Store에서 불필요하게 어떤 제품을 판매할 지에 대한 관심이 분리되지 않았기 때문이다.

public interface Product{
}
public class Pencil implements Product{
}
public class Store{
	private Product product;
    
    pblic Store(Product product){
    	this.product = product;
    }
  }

Stroe와 Pencil이 강하게 결합된 부분을 제거하기 위해 외부에서 상품을 주입 받아야 한다. 

그래야 Store에서 구체 클래스에 의존하지 않게 된다.

여기서 Spring이 DI 컨테이너를 필요로 하는 이유를 알 수 있는데,

Store에서 Product 객체 주입하기 위해 애플리케이션 실행 시점에 필요한 빈을 생성해야 하며,

의존성이 있는 두 객체를 연결하기 위해 한 객체를 다른 객체로 주입 시켜야 하기 때문이다.

public class BeanFactory{
	public void store(){
    	//Bean 생성
        Product pencil = new Pencil();
        //의존성 주입
        Store store = new Store(pencil);
    }
}

 

이러한 개념은 제어의 역전(Inversion of Control, IOC)라 불리기도 한다.

어떠한 객체를 사용할지에 대한 책임은 프레임워크에게 넘어갔고, 자신은 수동적으로 주입받는 객체를 사용하기 때문

 

출처 : https://mangkyu.tistory.com/150

 

[ 의존성 주입(Dependency Injection) 정리 ]

한 객체가 어떤 객체(구체 클래스)에 의존할 것인지는 별도의 관심사이다. Spring은 의존성 주입을 도와주는 DI 컨테이너로써, 강하게 결합된 클래스들을 분리하고, 애플리케이션 실행 시점에 객체 간의 관계를 결정해 줌으로써 결합도를 낮추고 유연성을 확보해준다. 이러한 방법은 상속보다 훨씬 유연하다. 단, 한 객체가 다른 객체를 주입받으려면 반드시 DI 컨테이너에 의해 관리되어야 한다는 것이다.

  • 두 객체 간의 관계라는 관심사의 분리
  • 두 객체 간의 결합도를 낮춤
  • 객체의 유연성을 높임
  • 테스트 작성을 용이하게 함