스프링(Spring)을 공부하다보면 의존성(Dependency)이라는 말을 자주 듣게 된다.
처음에는 어렵게 느껴질 수 있지만, 쉽게 풀어서 설명해보려 한다.
1. 의존성이란?
"A가 B를 필요로 한다" > 이것이 바로 의존성이다.
예를 들어, 자동차를 만든다고 생각해보자.
자동차에는 엔진, 바퀴, 핸들 같은 부품들이 필요하다.
즉, 자동차에는 엔진과 바퀴에 '의존'하고 있는 것이다.
코드에서도 마찬가지다.
어떤 클래스가 다른 클래스를 사용해야 할때 "의존성이 있다"라고 한다.
2. 스프링에서 의존성 관리하기
스프링에서는 이 의존성을 어떻게 관리할까?
직접 만드는 방식(안좋은 방법)
class Car {
Engine engine = new Engine(); // 직접 객체를 생성함
}
이렇게 Car 안에 Engine을 직접 생성하면 나중에 Engine을 바꾸기가 어렵다.
이런것을 "Car가 Engine에 강하게 묶여있다"라고 표현한다.
예로 가솔린 엔진에서 전기차 엔진으로 변경하고 싶을 때 불편하다
스프링에서 관리하는 방식은 다음과 같다(좋은 방법)
class Car {
private Engine engine;
public Car(Engine engine) { // 생성자를 통해 주입 (DI)
this.engine = engine;
}
}
이제는 Car는 Engine을 직접 만들지 않고 외부에서 받는다. 이것을 의존성 주입(Dependanccy Injection, DI)이라고 한다.
3. 스프링이 의존성을 관리하는 이유
그렇다면 스프링은 왜 의존성을 관리하는 걸까?
- 유연한 코드 작성 가능
- 가솔린 엔진, 전기 엔진을 쉽게 교체할 수 있다
- 유지보수가 편리하다
- 객체생성을 자동으로 해줌
- new 키워드를 직접 사용하지 않아도 된다
- 스프링이 알아서 객체를 만들어서 관리해준다
- 테스트가 쉬워짐
- 가짜(Fake) 객체를 만들어서 쉽게 테스트할 수 있다.
4. 의존성 주입(DI)의 3가지 방법
스프링에서는 의존성을 주입하는 방법이 3가지 있다.
- 생성자 주입(Constructor Injection) -> 가장 추천
@Component
class Car {
private final Engine engine;
@Autowired // 스프링이 자동으로 주입해줌
public Car(Engine engine) {
this.engine = engine;
}
}
2. 세터 주입(Setter Injection)
@Component
class Car {
private Engine engine;
@Autowired
public void setEngine(Engine engine) {
this.engine = engine;
}
}
3. 필드 주입 (Field Injection) → 비추천
@Component
class Car {
@Autowired
private Engine engine;
}
(주의!) 필드 주입은 테스트가 어렵고, 유지보수하기 힘들어서 많이 사용하지 않는다.
5. 결론
의존성 = 어떤 클래스가 다른 클래스를 필요로 하는 것
스프링은 의존성을 자동으로 관리해서 코드가 더 깔끔하고 유연하다
의존성 주입(DI) 덕분에 객체를 쉽게 바꿀 수 있고, 유지보수도 편리하다.
댓글