필드(Field), Setter, 생성자 의존성 주입

초코칩·2023년 1월 19일
1

spring

목록 보기
2/6
post-thumbnail

@Autowired

Spring에서 Bean 인스턴스가 생성된 이후 @Autowired를 설정한 메서드가 자동으로 호출되고, 인스턴스가 자동으로 주입된다.

Field 의존성 주입

다음과 같이 Field에 @Autowired를 적용할 수 있다.

@Service
@Transactional(readOnly = true)
public class MyService{

	@Autowired
	private MyRepository myRepository;
    
    ...
}

장점

  • 코드가 간결하다.

단점

  • 캡슐화로 인해 외부에서 접근이 불가능하다.
  • final을 사용하지 못해 불변성을 보장받지 못한다.
  • 순환 의존성 문제가 발생할 수 있다.
@Autowired
private UserService userService;

@Autowired
private PayService payService;

Setter 의존성 주입

다음과 같이 Setter 적용시 의존성을 주입한다.

@Service
@Transactional(readOnly = true)
public class MyService {

    private MyRepository myRepository;
    
    @Autowired
    public void setMyRepository(MyRepository myRepository) {
        this.myRepository = myRepository;
    }
    ...
}

장점

  • 컨테이너와의 결합도는 낮아져 테스트 코드를 짤 수 있다.

단점

  • Setter 메서드가 public이므로 의도치 않은 변경이 가능하다.
  • Field 주입의 final을 사용하지 못하는 문제, 순환 의존성에 관한 문제 등은 여전히 남아있다.

Constructor 의존성 주입

가장 권장하는 방식입니다.

@Service
@Transactional(readOnly = true)
public class MyService {

    private MyRepository myRepository;
    
    @Autowired
    public MyService(MyRepository myRepository) {
        this.myRepository = myRepository;
    }
    ...
}

@Autowired가 필요없다. 생성자가 하나인 경우 자동으로 @Autowired가 적용된다. 또한 MyRepository는 더 이상 변경하지 않기 때문에 final 키워드를 추가한다.

@Service
@Transactional(readOnly = true)
public class MyService {

    private final MyRepository myRepository;
    
    public MyService(MyRepository myRepository) {
        this.myRepository = myRepository;
    }
    ...
}

장점

  • 객체 생성 시점에 필수 의존성을 갖게 되어 객체가 항상 유효한 상태로 생성된다.
  • 불변성을 갖는 객체를 만들기에 용이하다.
  • 테스트 용이성이 향상된다.
  • Lombok과 결합하여 코드를 간결하게 쓸 수 있다.
  • 스프링에 비침투적인 코드 작성이 가능하다.
  • 순환 참조를 컴파일 타임에 방지할 수 있다.

Lombok을 이용한 축약

@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class MyService {

    private final MyRepository myRepository;
    ...

RequiredArgsConstructorfinal 키워드만 있는 변수의 생성자를 생성한다.

profile
초코칩처럼 달콤한 코드를 짜자

0개의 댓글