티스토리 뷰

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
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
글 보관함