[Spring] DI를 구현하는 3가지 방법

ggamang·2023년 4월 19일
0

JAVA&Spring

목록 보기
27/27

Spring Framework에서 DI(Dependency Injection)를 달성하는 방법은 크게 3가지가 있다

Constructor Injection

: 객체를 생성할 때 생성자를 통해 의존성을 주입하는 방식

public class UserServiceImpl implements UserService {
    private final UserRepository userRepository;

    public UserServiceImpl(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    // ...
}

UserServiceImpl 클래스는 UserRepository 인터페이스에 의존한다.

UserServiceImpl 클래스의 생성자에서 UserRepository 객체를 주입받고, 이후에 UserRepository를 사용할 때 userRepository 변수를 사용

장점

  • 코드의 가독성이 좋아진다
  • 의존성이 있는 객체를 생성할 때 의존성을 명시적으로 알려줘서 의존성 문제를 미리 방지할 수 있다
  • 생성자로 주입하면 객체(스프링 빈) 생성 전에 검증이 가능하다!

단점

  • 의존성이 많은 객체를 생성할 때 생성자의 인자가 많아져서 복잡해질 수 있다.

Setter Injection

: Setter 메서드를 통해 의존성을 주입하는 방식

public class UserServiceImpl implements UserService {
    private UserRepository userRepository;

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

    // ...
}

Setter Injection을 사용하여 UserRepository 객체를 주입받고, 이후에 UserRepository를 사용할 때 userRepository 변수를 사용한다

장점

  • 객체 생성 시점에서 의존성이 없어도 되기 때문에 객체의 생성과 의존성 주입이 분리되어 코드 유지보수성이 좋아진다

단점:

  • Setter 메서드를 호출하지 않은 경우에는 객체 생성 후에도 의존성이 없는 상태로 남아 있을 수 있다

Field Injection

: 필드에 직접 의존성을 주입하는 방식

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

    // ...
}

Field Injection을 사용하여 UserRepository 객체를 주입받고, 이후에 UserRepository를 사용할 때 userRepository 변수를 사용

장점

  • 코드량이 적어서 코드 가독성이 높아진다

단점

  • 객체 생성 시점에서 의존성이 없어도 되기 때문에 컴파일 타임에는 문제가 없어 보이지만, 런타임 시점에서 NPE(NullPointerException) 등의 예외가 발생할 수 있다.

생성자 주입을 사용하자!

  1. 코드 가독성이 좋다
    생성자 인자로 필요한 의존성을 명시적으로 알려주기 때문에, 코드가 무엇을 의미하는지 명확하게 드러난다.

  2. 의존성 주입을 보장한다.
    생성자 주입의 경우 객체를 생성하는 시점에 필요한 의존성을 모두 받아야 한다. 그렇기 때문에 객체 생성 후에도 의존성이 없는 상태로 남아 있을 가능성이 없어진다.

  3. 불변성(Immutability)이 보장된다.
    생성자에서 한 번만 의존성을 주입하므로, 해당 객체는 불변성을 보장할 수 있게 된다. 따라서 객체의 상태를 변경하는 위험성을 방지할 수 있다.

0개의 댓글