본문 바로가기

JAVA/Spring Framework

생성자 주입을 @Autowired를 사용하는 필드 주입보다 권장하는 하는 이유

728x90

Field injection is not recommended … Always use constructor based dependency injection in your beans

 

Spring에서 `@Autowired` 애노테이션을 사용하여 의존성을 주입할 때, 생성자 주입을 사용하지 않고 필드 주입(Field Injection)이나 세터 주입(Setter Injection)을 사용할 수 있습니다. 그러나 생성자 주입을 사용하지 않으면 몇 가지 문제가 발생할 수 있습니다:

 

### 필드 주입(Field Injection)

 

필드 주입은 필드에 직접 `@Autowired` 애노테이션을 붙여서 의존성을 주입하는 방식입니다.

 

#### 예제 코드

@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;

    public void performAction(String data) {
        userRepository.save(data);
    }
}

 

#### 문제점

1. **테스트의 어려움**: 필드 주입을 사용하면 의존성을 주입하기 위해 리플렉션을 사용해야 하기 때문에, 단위 테스트에서 Mock 객체를 주입하기 어렵습니다. Mockito와 같은 테스트 프레임워크를 사용할 때도 필드 주입을 처리하기 위해 특별한 설정이 필요합니다.

 

2. **불변성(Immutable) 위반**: 필드 주입은 객체가 생성된 후에 주입이 이루어지므로, 객체가 불변성을 가질 수 없습니다. 이는 객체의 상태 일관성을 보장하기 어렵게 만듭니다.

 

3. **숨겨진 의존성**: 필드에 직접 의존성을 주입하면, 클래스 외부에서는 해당 클래스가 어떤 의존성을 가지는지 알기 어렵습니다. 이는 코드의 가독성과 유지보수성을 떨어뜨립니다.

 

### 세터 주입(Setter Injection)

 

세터 주입은 세터 메서드에 `@Autowired` 애노테이션을 붙여서 의존성을 주입하는 방식입니다.

 

#### 예제 코드

@Service
public class UserService {
    private UserRepository userRepository;

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

    public void performAction(String data) {
        userRepository.save(data);
    }
}

 

 

#### 문제점

1. **부분 주입 가능성**: 세터 주입을 사용하면 객체가 생성된 후에 의존성을 주입받기 때문에, 일부 의존성이 주입되지 않은 상태로 객체가 사용될 수 있습니다. 이는 객체의 상태 일관성을 해칠 수 있습니다.

 

2. **불변성(Immutable) 위반**: 세터 주입도 필드 주입과 마찬가지로 객체가 불변성을 가질 수 없습니다. 이는 객체의 상태를 변경할 수 있는 메서드가 존재하게 되어 객체의 일관성을 유지하기 어렵게 만듭니다.

 

### 생성자 주입(Constructor Injection)의 장점

 

#### 예제 코드

@Service
public class UserService {
    private final UserRepository userRepository;

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

    public void performAction(String data) {
        userRepository.save(data);
    }
}

 

 

#### 장점

1. **불변성 보장**: 생성자 주입을 사용하면 의존성이 객체 생성 시에만 주입되기 때문에 객체가 불변성을 가질 수 있습니다. 이는 객체의 상태 일관성을 보장합니다.

 

2. **명시적인 의존성**: 생성자를 통해 의존성을 주입받으면 클래스 외부에서도 해당 클래스가 어떤 의존성을 가지는지 명확하게 알 수 있습니다. 이는 코드의 가독성과 유지보수성을 높입니다.

 

3. **테스트 용이성**: 생성자 주입을 사용하면 단위 테스트에서 의존성을 쉽게 주입할 수 있습니다. Mock 객체를 생성자에 전달하여 테스트할 수 있으므로 테스트 코드 작성이 용이합니다.

 

4. **완전한 객체 상태 보장**: 생성자 주입을 사용하면 객체가 완전히 초기화된 상태로 생성되기 때문에, 부분적으로 초기화된 객체가 사용될 가능성이 없습니다. 이는 객체의 일관성과 신뢰성을 높입니다.

 

결론적으로, 생성자 주입을 사용하지 않으면 객체의 상태 일관성 유지가 어려워지고, 테스트 코드 작성이 복잡해지며, 코드의 가독성과 유지보수성이 떨어질 있습니다. 따라서 Spring 애플리케이션에서는 가능한 생성자 주입을 사용하는 것이 권장됩니다.

'JAVA > Spring Framework' 카테고리의 다른 글

spring HandlerMapping - DispatherServlet설정  (0) 2021.06.01
spring viewResolver - DispatherServlet설정  (0) 2021.06.01
java spring mvc  (0) 2021.06.01
Spring Bean Container  (0) 2021.05.31
SOLID  (0) 2021.01.19