DI(의존성 주입) : Dependency Injection
DI 란 스프링이 제공하는 의존 관계 주입 기능. 객채를 직접 생성하지 않고, 외부에서 생성 후 주입한다.
이를 통해 모듈간의 결합도가 낮아지고 유연성이 높아지게 된다.

방법 1은 A객체가 B,C 객체를 new 생성자를 통해 직접 생성하는 방법이고.
방법 2는 DI 의 예시로 외부에서 생성된 객체를 setter를 통해 주입하는 방법이다.

스프링에서는 이 객체들을 Bean 이라고 칭하고, 프로젝트가 실행될떄 사용자가 Bean으로 관리하는 객체들의 생성과 소멸에 관련된 작업들을 자동적으로 수행해준다.
이때 객체가 생성회는 곳을 스프링에서는 Bean 컨테이너 라고 부른다
DI를 사용해야하는 이유는 다음과 같다.
- Test가 용이해진다.
- 코드의 재사용성을 높여준다.
- 객체간의 의존성(종속성)을 줄이거나 없앨 수 있다.
- 객체간의 결합도를 낮추면서 유현한 코드를 작성할 수 있다.
DI(의존성 주입) 예제
1. 생성자 주입. (Constructor Injection)
public class PostController {
private final PostService postService;
public PostController(PostService postService) {
this.postService = postService;
}
}
장점
- 순환 참조를 방지할 수 있다.반면, 생성자 주입을 사용하게 되면, BeanCurrentlyInCreationException이 발생하게 되어 어플리케이션을 실행하는 시점에서 오류를 체크할 수 있다.
- 필드 주입과 수정자 주입은, 빈이 생성된 이후 참조를 하기 때문에, 어플리케이션이 아무런 오류, 경고 없이 구동이 되어 실제 코드가 호출될 때까지 문제를 알 수 없다.
- 불변성다른 방법을 사용할 경우 불필요하게 수정의 가능성을 열어두게 되어 OCP(개방-폐쇠의 원칙) 를 위반하게 된다.
- final 로 선언 가능해 런타임에서 의존성을 주입받는 객체가 변할 일이 없어진다.
- 테스트에 용이하다.
단점
- 코드가 상대적으로 길다
2. 필드 주입 (Field Injection)
public class PostController {
@Autowired
private final PostService postService;
}
}
장점
- 코드가 간결하다
단점
- 외부에서 변경하기 힘들다.
- 프레임워크에 의존적이다.
3. 수정자 주입 (Setter Injection)
public class PostController {
@Autowired
private final PostService postService;
}
}
단점
- setter를 public으로 열어두어야 하기 떄문에 언제 어디서든 변경이 가능하다.
이처럼 의존성 주입의 방식에는 생성자, 필드, 수정자를 통한 주입방법이 있지만, 다음과 같은 이유로
Spring Framework Reference 에서 권장하는 주입 방식은 생성자를 통한 주입이다.
참고 자료
DI(의존성 주입) : Dependency Injection
DI 란 스프링이 제공하는 의존 관계 주입 기능. 객채를 직접 생성하지 않고, 외부에서 생성 후 주입한다.
이를 통해 모듈간의 결합도가 낮아지고 유연성이 높아지게 된다.

방법 1은 A객체가 B,C 객체를 new 생성자를 통해 직접 생성하는 방법이고.
방법 2는 DI 의 예시로 외부에서 생성된 객체를 setter를 통해 주입하는 방법이다.

스프링에서는 이 객체들을 Bean 이라고 칭하고, 프로젝트가 실행될떄 사용자가 Bean으로 관리하는 객체들의 생성과 소멸에 관련된 작업들을 자동적으로 수행해준다.
이때 객체가 생성회는 곳을 스프링에서는 Bean 컨테이너 라고 부른다
DI를 사용해야하는 이유는 다음과 같다.
- Test가 용이해진다.
- 코드의 재사용성을 높여준다.
- 객체간의 의존성(종속성)을 줄이거나 없앨 수 있다.
- 객체간의 결합도를 낮추면서 유현한 코드를 작성할 수 있다.
DI(의존성 주입) 예제
1. 생성자 주입. (Constructor Injection)
public class PostController {
private final PostService postService;
public PostController(PostService postService) {
this.postService = postService;
}
}
장점
- 순환 참조를 방지할 수 있다.반면, 생성자 주입을 사용하게 되면, BeanCurrentlyInCreationException이 발생하게 되어 어플리케이션을 실행하는 시점에서 오류를 체크할 수 있다.
- 필드 주입과 수정자 주입은, 빈이 생성된 이후 참조를 하기 때문에, 어플리케이션이 아무런 오류, 경고 없이 구동이 되어 실제 코드가 호출될 때까지 문제를 알 수 없다.
- 불변성다른 방법을 사용할 경우 불필요하게 수정의 가능성을 열어두게 되어 OCP(개방-폐쇠의 원칙) 를 위반하게 된다.
- final 로 선언 가능해 런타임에서 의존성을 주입받는 객체가 변할 일이 없어진다.
- 테스트에 용이하다.
단점
- 코드가 상대적으로 길다
2. 필드 주입 (Field Injection)
public class PostController {
@Autowired
private final PostService postService;
}
}
장점
- 코드가 간결하다
단점
- 외부에서 변경하기 힘들다.
- 프레임워크에 의존적이다.
3. 수정자 주입 (Setter Injection)
public class PostController {
@Autowired
private final PostService postService;
}
}
단점
- setter를 public으로 열어두어야 하기 떄문에 언제 어디서든 변경이 가능하다.
이처럼 의존성 주입의 방식에는 생성자, 필드, 수정자를 통한 주입방법이 있지만, 다음과 같은 이유로
Spring Framework Reference 에서 권장하는 주입 방식은 생성자를 통한 주입이다.
참고 자료