Spring DI 방식에 대한 차이

이동명·2023년 6월 26일
1
post-thumbnail

의존성 주입의 방법에 대해서 차이점을 알아보자.

 	private UserService service;
    
    private DefaualtMailServiceInterImpl registerMail;

    public UserController(UserService service, DefaualtMailServiceInterImpl registerMail) {
        this.service = service;
        this.registerMail = registerMail;
    }
    

현재는 생성자 방식으로 주입을 하고 있다. 하지만..

  • 롬복 생성자 인젝션

  • setter autowired 인젝션

    등등 무엇으로 또 할 수 있으며 각자의 차이가 무엇인지 분석하고 알고가자.

피드백 문제 해결

생성자 주입(Constructor Injection):

  • 생성자 주입은 클래스의 생성자를 통해 의존성을 주입하는 방식입니다.

  • 주입 받을 의존성을 final로 선언할 수 있어 불변성을 보장할 수 있습니다.

  • 객체 생성 시점에 의존성이 모두 주입되므로, 객체의 일관성과 안정성을 보장할 수 있습니다.

  • 테스트하기 쉽고 의존성이 명시적으로 드러나므로 코드의 가독성과 유지보수성을 높일 수 있습니다.

@Service
public class UserService {

    private UserRepository userRepository;
    private MemberService memberService;

    public UserService(UserRepository userRepository, MemberService memberService) {
        this.userRepository = userRepository;
        this.memberService = memberService;
    }

}

필드 주입(Field Injection):

  • 필드 주입은 의존성을 클래스의 필드에 직접 주입하는 방식입니다.

  • 주입 받을 의존성을 public 또는 private 필드로 선언합니다.

  • 코드의 양을 줄일 수 있고, 편리한 구현이 가능합니다.

  • 하지만 의존성이 외부에서 직접 접근 가능하므로 캡슐화 원칙에 어긋날 수 있고, 테스트하기 어렵고 유연성이 떨어질 수 있습니다.

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;
    @Autowired
    private MemberService memberService;

}

세터 주입(Setter Injection):

  • 세터 주입은 의존성을 객체의 세터 메서드를 통해 주입하는 방식입니다.

  • 의존성 주입 순서가 유연하게 조정될 수 있어서 일부 의존성만 필요한 경우에 유용합니다.

  • 선택적으로 의존성을 주입할 수 있으므로, 의존성이 필수적이지 않은 경우 유연하게 처리할 수 있습니다.

  • 하지만 세터 메서드가 많아지면 코드의 가독성이 저하될 수 있으며, 세터 메서드를 통해 잘못된 의존성을 주입할 수 있는 위험성도 있습니다.

@Service
public class UserService {

    private UserRepository userRepository;
    private MemberService memberService;

    @Autowired
    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Autowired
    public void setMemberService(MemberService memberService) {
        this.memberService = memberService;
    }
}

필드 주입(Field Injection)이 권장되지 않는 자세한 이유

  • 캡슐화 원칙 위반: 필드 주입은 주입 받을 의존성을 public 또는 private 필드로 선언합니다. 이는 객체의 캡슐화 원칙을 위반하는 것입니다. 의존성이 외부에서 직접 접근 가능하므로 객체의 내부 상태를 외부에서 변경할 수 있으며, 객체의 일관성과 불변성을 유지하기 어렵게 됩니다.

  • 유연성의 감소: 필드 주입은 의존성을 주입받을 필드를 final로 선언할 수 없으므로, 필드의 변경이 자유롭게 이루어질 수 있습니다. 이는 의존성이 변경될 경우 해당 필드를 사용하는 모든 부분을 수정해야 한다는 의미입니다. 이로 인해 유지보수성이 저하되며, 의존성 변경에 따른 리팩토링 비용이 증가합니다.

  • 테스트의 어려움: 필드 주입은 의존성을 객체의 필드에 직접 주입하므로, 테스트할 때 의존성을 모의(mock) 객체로 대체하기 어렵습니다. 의존성을 목적에 맞게 대체하여 테스트하려면 필드에 접근할 수 있는 setter 메서드나 다른 방법을 통해 값을 변경해야 합니다.

  • 의존성 감추기 어려움: 필드 주입은 의존성이 클래스의 필드에 직접 노출되므로, 해당 클래스가 어떤 의존성을 사용하는지를 외부에 노출시킵니다. 이는 클래스의 구현 세부 사항을 외부에 노출시키고, 의존성의 변경으로부터 자유로워지기 어렵게 만듭니다.


profile
Web Developer

0개의 댓글