Don't call us. we'll call you 이는 제어의 역전에 대한 비유적 표현이다.
Inversion of Control
제어의 역전 Ioc
클래스 A에서 클래스 B 객체 생성 예
public class A {
b = new B(); # 클래스 A 에서 new 키워드로 클래스 b의 객체 생성
}
제어의 역전은 다른 객체를 직접 생성하거나 제어하는 것이 아니라 외부에서 관리하는 객체를 가져와 사용하는 것을 말한다. 코드를 보면 쉽게 이해할 수 있다. 위 코드를 제어의 역전을 적용하면 다음과 같이 코드의 형태가 바뀐다.
스프링 컨테이너가 객체를 관리하는 방식 예
public class A {
private B b; #코드에서 객체를 생성하지 않음, 어디선가 받아온 객체를 b에 할당.
}
스프링에서는 제어의 역전 개념을 중요한 컨셉으로 삼고 있으며, 방금까지 설명한 내용에서 외부 (= 객체를 관리하고 관리하는 주체)를 "스프링 컨테이너" 라고 한다.
스프링 컨테이너
자바 객체의 생명 주기를 관리하먀, 생성된 자바 객체들에게 추가적인 기능을 제공한다.
스프링에서는 자바 객체를 빈(bean)이라 한다.
즉, 스프링 컨테이너는 내부에 존재하는 빈의 생명주기를 관리(빈의 생성, 관리, 제거 등) 하며, 생성된 빈에게 추가적인 기능을 제공하는 것이다. 객체 관리의 부담을 줄일 수 있다.
스프링 컨테이너는 XML,어노테이션 기반의 자바 설정 클래스로 만들 수 있다.
스프링 부트를 사용하기 이전에는 xml 을 통해 직접적으로 설정해 주어야 했지만, 스프링 부트가 등장하면서 대부분 사용하지 않게 되었다.
스프링 컨테이너는 Beanfactory 와 ApplicationContext 두 종류의 인터페이스로 구현되어 있다.
빈 팩토리는 빈의 생성과 관계설정 같은 제어를 담당하는 IoC 오브젝트이고, 빈 팩토리를 좀 더 확장한 것이 애플리케이션 컨텍스트 이다.
스프링 컨테이너의 기능
스프링 컨테이너는 빈(Bean)의 인스턴스화, 구성, 전체 생명 주기 및 제거까지 관리한다.
스프링 컨테이너를 통해 원하는 만큼 많은 객체를 가질 수 있다.
의존성 주입 (DI)을 통해 애플리케이션의 컴포넌트를 관리할 수 있다.
스프링 컨테이너는 서로 다른 빈을 연결하여 애플리케이션 빈을 연결하는 역할을 한다.
사용하는 이유
1) 객체를 생성하기 위해서는 new생성자를 사용해야 한다. -> 의존성이 높아짐. (강한 결합) 유연함 하락.
2) 스프링 컨테이너 사용 -> 객체간의 의존성을 낮추며, 결합도를 낮추고, 높은 캡슐화를 기대할 수 있다.
Dependency Injection
DI
객체들을 관리하기 위해 제어의 역전을 사용한다. 그리고 제어의 역전을 구현하기 위해 사용하는 방법이 DI 이다.
DI는 어떤 클래스가 다른 클래스에 의존한다는 뜻이다.
객체를 주입받는 모습 예)
public class A{
#A에서 B를 주입받음
@Autowired
B b;
}
@Autowired라는 애너테이션은 스프링 컨테이너에 있는 빈이라는 것을 주입하는 역할이다.
빈은 쉽게 말해 스프링 컨테이너에서 관리하는 객체이다. 이전 코드에서는 개발자가 직접 B 객체를 생성했지만 다음 코든는 어딘가에 B b; 라고 선언했을 뿐 직접 객체를 생성하지 않고 있다. 다시 말해서 객체를 주입받고 있는 것이다.
의존성 주입
주입 ( 생성자 주입 , 세터 주입, 인터페이스 주입)
v0에서는 잘 안쓰인다.
VO(Value Object) 객체에서는 의존성 주입이 잘 사용되지 않는 것이 일반적이다.
VO 객체의 특징
- 불변성(Immutability): VO 객체는 일반적으로 불변 객체로 설계된다. 즉, 한 번 생성된 후에는 상태가 변하지 않는 것이 VO 객체의 중요한 특성 중 하나이다. 불변성을 유지하는 이유는 VO가 주로 값(데이터)을 표현하고 비교하는 역할을 하며, 상태 변화를 관리하는 것이 아닌 데이터 전송에 초점을 맞추기 때문이다.
- 단순한 데이터 저장소 역할: VO 객체는 상태를 유지하거나 비즈니스 로직을 처리하는 것이 아닌, 데이터를 담아 전달하는 목적을 가지고 있다. DTO(Data Transfer Object)나 단순 데이터 클래스로 사용되며, 복잡한 의존성을 주입하거나 관리하는 역할을 하지 않는다.
- 의존성 주입이 불필요: VO 객체는 데이터를 표현하기 위한 것이므로, 외부의 서비스나 리소스에 의존하는 경우가 거의 없다. 의존성 주입은 보통 서비스 계층이나 비즈니스 로직을 수행하는 클래스에서 필요하며, VO에서는 이를 필요로 하지 않는다.
의존성 주입이 필요한 경우
VO 객체는 대개 의존성 주입이 필요하지 않지만, 만약 VO가 데이터를 단순히 담는 것 이상을 하거나, 외부 서비스나 컴포넌트와 상호작용하는 경우가 있다면 의존성 주입이 고려될 수 있다. 그러나 이는 일반적인 VO 설계 철학과는 맞지 않기 때문에 잘 사용되지 않는다.
결론적으로 VO 객체는 주로 데이터를 담는 단순한 객체이기 때문에 의존성 주입을 사용할 필요가 거의 없다. 의존성 주입은 주로 서비스 계층이나 컨트롤러와 같이 비즈니스 로직을 수행하는 객체에서 많이 사용된다.
참조) https://shinsunyoung.tistory.com/133
참조)https://ittrue.tistory.com/220