spring(스프링)

[spring(스프링)] 의존성 주입의 3가지 방법 _디버깅의 눈물

디버깅의 눈물 2023. 4. 12. 17:10

1. 생성자 주입(Constructor Injection)

 

public class UserServiceImpl implements UserService {
    private final UserRepository userRepository;
    private final EmailService emailService;

    // 생성자를 통해 의존 객체를 주입받습니다.
    public UserServiceImpl(UserRepository userRepository, EmailService emailService) {
        this.userRepository = userRepository;
        this.emailService = emailService;
    }

    // UserService 인터페이스의 메소드를 구현합니다.
    // 생성자에서 주입받은 의존 객체를 사용합니다.
    @Override
    public void registerUser(User user) {
        userRepository.save(user);
        emailService.sendEmail(user.getEmail(), "Welcome to our website!");
    }
}

 

 

생성자를 통해 의존성을 주입하는 방식입니다. 위 코드에서 UserServiceImpl 클래스는 생성자를 통해 UserRepository와 EmailService 인터페이스를 주입 받아 사용합니다. 이 방식은 객체 생성 시점에 모든 의존 객체를 주입 받습니다. 생성자 방식의 의존성 주입은 클래스 생성 시점에 필요한 의존성을 명시적으로 보여줄 수 있습니다.

 

또한 생성자 주입 방식은 해당 클래스에서 하나의 생성자만 구현하면 되기 때문에 코드 중복을 줄이고 유지보수성을 높일 수 있습니다.

 

 

2. 세터 주입(Setter Injection)

 

public class UserServiceImpl implements UserService {
    private UserRepository userRepository;
    private EmailService emailService;

    // 기본 생성자를 정의합니다.
    public UserServiceImpl() {
    }

    // UserRepository의 세터 메소드를 정의합니다.
    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    // EmailService의 세터 메소드를 정의합니다.
    public void setEmailService(EmailService emailService) {
        this.emailService = emailService;
    }

    // UserService 인터페이스의 메소드를 구현합니다.
    // 세터 메소드에서 주입받은 의존 객체를 사용합니다.
    @Override
    public void registerUser(User user) {
        userRepository.save(user);
        emailService.sendEmail(user.getEmail(), "Welcome to our website!");
    }
}

 

 

세터 메서드를 통해 의존성을 주입하는 방식입니다. 위 코드에서 UserServiceImpl 클래스는 세터 메서드를 통해 UserRepository와 EmailService 인터페이스를 주입받아 사용합니다. 이 방식은 객체 생성 후에 주입되므로, 객체 생성 시점과 의존 객체의 설정 시점이 분리되어 있어서 유연성이 높습니다.

하지만 여러 개의 세터 메서드가 존재하는 경우, 코드의 가독성이 떨어지고 유지보수가 어려워질 수 있습니다. 

 

 

 

3. 필드 주입(Field Injection)

 

public class UserServiceImpl implements UserService {
    @Autowired
    private UserRepository userRepository;

    @Autowired
    private EmailService emailService;

    // UserService 인터페이스의 메소드를 구현합니다.
    // 필드에서 주입받은 의존 객체를 사용합니다.
    @Override
    public void registerUser(User user) {
        userRepository.save(user);
        emailService.sendEmail(user.getEmail(), "Welcome to our website!");
    }
}

 

 

필드에 직접적으로 의존성을 주입하는 방식입니다. 스프링에서는 필드에 @Autowired 어노테이션을 사용하여 해당 클래스의 인스턴스를 생성할 때, 자동으로 필요한 의존성을 주입합니다.

 

필드를 사용한 의존성 주입은 주입되는 의존성이 명시적으로 나타나지 않습니다. 이는 코드 가독성과 유지보수성을 저하시킬 수 있습니다.

 

*의존성을 명시적으로 주입한다는 것은 객체를 생성할 , 객체가 필요로 하는 의존성을 생성자나 Setter 메서드를 통해 외부에서 주입하는 것을 말합니다.