DI (Dependency Injection)
외부에서 두 객체 간의 관계를 결정해주는 디자인 패턴이다.
두 객체 사이에 인터페이스를 둬 클래스 레벨에서는 의존관계가 고정되지 않도록 하고, 런타임시에 관계를 주입하여 유연성 확보 및 결합도 낮춘다.
public class MyRoom(){
private Desk desk;
}
public class Desk(){
}
에서 MyRoom 객체가 Desk 객체에 의존성을 지닌다.
여기서,
public class MyRoom(){
private Desk desk;
public MyRoom(){
this.desk = new Desk();
}
}
일 경우 결합도가 매우 높다는 문제가 발생한다.
왜냐하면, 내 방에 어떤 물건이 있는지에 대한 관심이 분리되지 않았기 떄문
그리고 또 다른 문제는, 위는 객체간 관계가 아니라 클래스간 관계가 형성되었다.
객체지향이라면 객체간의 관계가 형성되야 되는데 클래스간 관계가 형성된 것.
→ 다른 객체의 구체 클래스를 알지 못해도 인터페이스의 타입으로 사용할 수 있도록 해야한다.
여기서 의존성 주입을 하는 방법은 다음과 같다.
객체관 관계를 맺기 위해 인터페이스를 구성한다.
첫째, 객체관 관계를 맺기 위해 인터페이스를 구성한다.
public interface Furniture(){
}
public class Desk implements Furniture(){
}
둘째, 결합도를 낮추기 위해 외부에서 Desk를 주입받도록 한다
public class MyRoom(){
private Furniture furniture;
public MyRoom(Furniture furniture){
this.Furniture = furniture
}
}
그럼 이제 여기서 DI 컨테이너의 필요성을 알 수 있다.
MyRoom에서 Furniture 객체를 주입받기 위해선 앱 실행 시점에 필요한 객체를 생성해야 한다.
그리고 의존성이 있는 두 객체를 연결하기 위해 한 객체를 다른 객체로 주입시켜야 하기 때문이다.
그렇기에, 객체 주입을 DI 컨테이너가 담당하게 되어 제어 역전(IoC)이 일어나게 된다.
추가로, Spring4부터는 여러 의존성 주입 방법중 위에서 예시를 든 ‘생성자 주입’ 방법을 권장한다.
(스프링에선, 생성자가 하나만 존재할경우 @Autowired 어노테이션을 생략해도 주입을 지원한다.)
이외의 주입방법도 존재하는데, 두 가지가 있다.
getter setter를 통한 주입
이는 주입받는 객체가 변경될 가능성이 있다면 사용한다.
public class MyRoom(){
private Furniture furniture;
@Autowired
public void setFurniture(Furniture furniture){
this.furniture = furniture;
}
}
필드 주입
생성자나 setter를 사용하지 않고 바로 필드에 의존 관계를 두는 방법이다.
단점으로는 외부에서 접근이 불가능하다는 점, 필드 주입은 반드시 DI 프레임워크가 존재해야한다는 점이다.
그리고 필드의 객체를 수정할 수 없기 때문에 테스트 코드에 불리하다.
public class MyRoom(){
@Autowired
private Furniture furniture;
}
'IDE & Framework > Spring' 카테고리의 다른 글
[단축 URL 프로젝트 URLumberjack] - devOps 정의 (0) | 2023.04.24 |
---|---|
Spring boot 서버를 Gradle로 build해 jar로 직접 배포하기 (0) | 2022.06.29 |
[Spring] MyBaits Insert 후 ID 받기 (짧) (0) | 2022.05.23 |
[Spring] 관념지향 프로그래밍(Aspect Oriented Promgramming) (0) | 2022.05.03 |
[Spring] @Scheduled cron 표현식 (0) | 2022.04.19 |