의존성 주입(DI, Dependency Injection)
의존성이라는 것은 하나의 객체가 다른 객체 없이 제대로 된 역할을 할 수 없다는 것을 의미한다.
ex) 음식점이라면 서빙을 담당하는 직원이 갑자기 하루 못나오는 상황이 있어도 장사는 할 수 있지만, 주방장에게 문제가 생겨서 못 나오면 장사를 할 수 없다 => 음식점이 주방장에 의존적
의존성은 이처럼 하나의 객체가 다른 객체의 상태에 따라 영향을 받는 것을 의미한다.
A 객체가 B 객체 없이 동작이 불가능한 상황을 'A가 B에 의존적이다'라고 표현한다.
주입은 말 그대로 외부에서 밀어 넣는 것을 의미한다.
ex) 어떤 음식점의 경우 매일 가게를 열기 전 직접 식재료를 구하기 위해 시장을 가지만, 프랜차이즈 식당들은 본사가 식재료를 공급합니다. 이 두 방식에서는 객체를 얻기 위해서 주체가 능동적인지 수동적인지의 차이가 있다.
위에서 설명한 의존성과 주입을 결합해서 생각해보면 '어떤 객체가 필요한 객체를 외부에서 밀어 넣는다' 라는 의미가 된다.

스프링은 이러한 구조를 만드는데 적합한 구조로 설계되어 있다. ApplicationContext가 필요한 객체들을 생성하고, 필요한 객체들을 주입하는 역할을 해 주는 구조이다. ApplicationContext가 관리하는 객체들을 빈(Bean)이라고 부른다.
그렇다면 왜 의존성 주입을 사용하는 것일까?
음식점의 예에서 직접 식재료를 사지 않고 대행 업체에서 배송해 주는 것을 사용하는 경우에 얻는 장점은 편리하다, 장사에만 집중할 수 있다 등이 있다. 이를 코드에 대입해서 살펴보면 '주입을 받는 입장에서는 어떤 객체인지 신경 쓸 필요가 없다.' '어떤 객체에 의존하든 자신의 역할은 변하지 않는다'와 같은 의미로 볼 수 있다.
의존성 주입은 IoC(Inversion of Control, 제어의 역전) 원칙 하에 객체간의 결합을 약하게 해주고 유지보수가 좋은 코드를 만들어준다. 또한 개발자들이 객체를 생성하는 번거로움과 다양한 케이스를 고려하는 경우를 줄이고, 변수 사용과 개발에 더욱이 집중할 수 있게 해준다.
IoC(Inversion of Control, 제어의 역전) : 객체 관리의 주체가 개발자가 아니라 컨테이너라는 의미
의존성 주입 장점
- Dependency Reduction : 객체 상호 간 의존성 관계를 줄여줌
- Reusable Structure : 코드의 재사용과 조합이 용이
- Readability : 코드 분리로 인한 가독성 향상
- Loose Coupling & Easy to change : 구조는 변화에 민감하지 않을 수 있음
DI를 왜 사용해야하는지 알아보았다. 이제 DI를 어떻게 사용하는지 알아보자.
의존성 주입 방법
의존성 주입 방법에는 3가지 방법이있다.
- 필드 주입(Field Injection)
- 세터 주입(Setter Injection)
- 생성자 주입(Constructor Injection)
Spring 3.x 버전까지만 해도 Setter Injection을 권장하였지만 Spring 4.3 이후 버전부터는 Contructor Injection를 권장한다.
필드, 세터, 생성자에 의존성을 주입할때는 과거부터 사용해오는 XML 설정 방식과 스프링에서 제공해주는 어노테이션(@)을 활용하는 방식이 있다.
XML 설정 방식은 XML 안에서 빈을 사용하여 의존성을 주입하는 방식이고 어노테이션 활용 방식은 생성자, 세터, 필드에 @AutoWired를 달아주어 의존성을 주입하는 방식이다.
지금은 어노테이션을 사용하는 방식을 사용하여 알아보고 나중에 XML을 사용하는 방식도 알아보겠다.
1. 필드 주입(Field Injection)
@Service
public class MemberServiceImpl implements MemberService{
@Autowired
private MemberService memberService;
}
필드 주입은 코드가 간결하여 과거에 많이 사용되었던 방식지만 이제 권장되지 않는다.
2. 세터 주입(Setter Injection)
@Service
public class MemberServiceImpl implements MemberService{
private MemberService memberService;
@Autowired
public void setMemberService(MemberService memberService) {
this.memberService = memberService;
}
}
3. 생성자 주입(Constructor Injection)
@Service
public class MemberServiceImpl implements MemberService{
private MemberService memberService;
@Autowired
public MemberServiceImpl(MemberService memberService) {
this.memberService = memberService;
}
}
생성자 주입 방식은 spring에서 가장 권장하는 방식이다.
스프링 4.3 이후 버전부터는 생성자가 1개만 있을 경우에는 @Autowired를 생략해도된다.
출처
[남가람북스] 코드로 배우는 스프링 웹 프로젝트
'WEB' 카테고리의 다른 글
[Tool] 파워목업을 사용해보자 (0) | 2021.12.22 |
---|---|
[Spring] Spring 이란? (0) | 2021.12.18 |
[JQuery] Ajax 구현하기 / 장단점 / 구조 / 예제 (0) | 2021.11.30 |
[JQuery] Fotorama 사용해보기 / 이미지 슬라이드 만들기 (0) | 2021.11.30 |
[JQuery] plugin 사용해서 DateTimePicker 만들기 (0) | 2021.11.30 |