티스토리 뷰
DI(Dependency Injection)이란?
-스프링에서 객체 간의 의존성을 관리하는 방법, 객체가 필요로하는 타 객체를 직접 생성하지않고, 외부에서 주입받는 방식으로 동작합니다. 이를 통해 객체 간의 결합도를 낮추고 유연하고 확장 가능한 코드를 작성할 수 있습니다. 쉽게말해서, 한 객체내에서 각자 코드구현에 필요한 타 객체가 있을겁니다. 여기서 필요한 객체를 내부 코드에서 직접 생성하게 되면 결합도가 높아져 나중에 코드변경이 있을때, 복잡해 집니다. 따라서, 내부에서 직접 생성하는 것이아닌 외부에서 주입받는 방식으로, 결합도를 낮춰 유지보수를 쉽게할 수 있게 만드는법을 말합니다.
DI가 필요한 이유
public interface Recipe{
}
public class Ramen implements Recipe{
}
public class Rice implements Recipe{
}
public class Hamburger implements Recipe{
}
예를 들어 위와 같은 레시피가 있다고 가정하겠습니다. Recipe라는 인터페이스가 있고, 그걸 구현하는 Ramen,Rice,Hamburger와 같은 클래스가 있습니다.
public class Chef{
private Recipe recipe;
public Chef() {
this.recipe = new Ramen();
}
}
Chef라는 클래스입니다. 해당클래스는 Recipe를 가지고 있어 해당 레시피에 해당하는 요리가 가능한 클래스입니다. 위의 코드를보시면 해당 셰프는 라멘레시피를 가지고있어, 라멘을 요리할 수 있습니다. 하지만 이 요리사가 라멘만 하면 괜찮지만,다른 요리를 해야한다고 했을때, 직접 생성자를 수정하여 레시피를 수정해야합니다. 이런식으로 진행을 하게되면 새로운 요리를할때마다 생성자를 수정해서 직접 레시피를 바꿔줘야 하기때문에 매우 비효율적이고 복잡해집니다.
public class Chef{
private Recipe recipe;
public Chef(Recipe recipe) {
this.recipe = recipe();
}
}
해당 코드는 DI의 생성자 주입방식으로 변경한 코드입니다. 보시면 내부에서 레시피를 생성하는 방식이 아닌 외부에서 생성자를 호출할때, 생성하여 가져오는 방식입니다. 외부에서 실행하는 코드는 다음과같습니다.
Chef1 = new Chef(new Ramen());
Chef2 = new Chef(new Rice());
Chef3 = new Chef(new Hamburger());
위의 코드는 외부에서 직접 레시피를 주입하는 코드입니다. 요리할 종류가 달라져 레시피가 바뀌더라고 직접 내부 생성자코드를 변경하지않아도, 외부에서 레시피만 바꿔주기만하면 레시피가 바뀌어 셰프가 다른요리를 할 수 있게됩니다. 이렇게 DI는 외부에서 결정하여 주입해주는 방식입니다.
DI구현 방법
- 생성자 주입(Constructor Injection)
-생성자를 통해 주입하는 방식
-주입받을 것을 생성자 매개변수로 선언하고, 스프링 컨테이너가 외부에서 결정하여 주입합니다.
-객체를 생성하는 시점에 주입하므로, 객체를 완전히 초기화하여 사용할 수 있습니다.
-코드가 길어지고 복잡해질 수 있으며, 매개변수가 많아질 수 있습니다.
public class UserService {
private UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
- 세터 주입(Setter Injection)
-세터 메서드를 통해 주입하는 방식
-세터 메서드로 정의하고, 스프링 컨테이너가 세터에 주입하는 방식
-선택적인 주입을 할 수 있어서 유연성이 높습니다.
-객체 생성 이후에도 의존성 변경될 수 있어 안정성이 보장되지 않을 수 있습니다.
public class UserService {
private UserRepository userRepository;
public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
- 필드 주입(Field Injection)
-인스턴스 변수로 직접 주입하는방식
-'@Autowired' 어노테이션을 사용하여 스프링 컨테이너가 해당 의존성을 자동으로 주입하는 방식
-코드가 간결해집니다.
-코드를 이해하기 어려워 질 수 있으며, 테스트용이성이 저하될 수 있습니다.
public class UserService {
@Autowired
private UserRepository userRepository;
}
'자바 > 스프링' 카테고리의 다른 글
WAS(Web Application Server) , DispatcherServlet (0) | 2023.06.24 |
---|---|
스프링 Controller, Repositroy, Service (0) | 2023.05.30 |
빈(Bean)등록 (컴포넌트,빈) (0) | 2023.05.30 |
Spring이란? (0) | 2023.05.14 |
빌드 관리 도구 (maven,gradle) (0) | 2023.05.14 |