DI(Dependency Injection) 및 제어의 역전 (IoC: Inversion of Control)
Spring Dependency Injection이란, 각 객체 간 의존관계를 스프링 컨테이너가 개발자가 정의한 Bean 등록 정보를 바탕으로 자동으로 주입해주는 기능이다.
일반적인 다양한 기존 스프링 프로젝트를 보면, Controller에서 Service나 Repository 객체를 사용 시, new 키워드를 통해 컨트롤러에서 객체를 직접 생성하여 사용하지 않고 의존성 주입을 통해 스프링 컨테이너에 생성된 객체를 받아 사용하고 있는 것을 볼 수 있다.
@Component, @Service, @Repository, @Controller 등의 어노테이션이 붙은 클래스들은 스프링 실행 시 스캔을 통해 개발자가 정의한 의존성 정보를 자동으로 bean 설정 정보에 등록을 하게 되어 의존성 주입이 동작하게 한다. --> 스프링 빈에서 다시 설명.
제어의 역전이란, 사용자가 자신이 필요한 객체를 생성해서 사용하는 것에 비해 용도에 맞게 필요한 객체를 그냥 가져다 사용 하는 것이다.
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) 만약, 생성자에 DB 접속 id, pw 를 추가하는 것으로 변경된다면..
public class Repository1 {
public Repository1(String id, String pw) {
// DB 연결
Connection connection = DriverManager.getConnection("jdbc:h2:mem:springcoredb", id, pw);
}
}
1). 각 객체에 대한 객체 생성은 딱 1번만!!
2). 생성된 객체를 모든 곳에서 재사용!!!
a) Repository1 클래스 선언 및 객체 생성 → repository1
public class Repository1 { ... }
// 객체 생성
Repository1 repository1 = new Repository1();
b) Service1 클래스 선언 및 객체 생성 (repostiroy1 사용) → service1
Class Service1 {
private final Repository1 repitory1;
// repository1 객체 사용
public Service1(Repository1 repository1) {
this.repository1 = repository1;
}
}
// 객체 생성
Service1 service1 = new Service1(repository1);
c) Contoller1 선언 ( service1 사용)
Class Controller1 {
private final Service1 service1;
// service1 객체 사용
public Controller1(Service1 service1) {
this.service1 = service1;
}
}
[개선 결과]
⇒ Repository1 생성자 변경은 이제 누구에게도 피해(?) 를 주지 않음
⇒ Service1 생성자가 변경되면? 모든 Contoller → Controller 변경 필요 X
결론적으로, 강한 결합 ⇒ 느슨한 결합
출처 : 항해99 스프링 심화강의 자료.