본문 바로가기

자바/스프링, 스프링부트

필드 주입 vs 생성자 주입

1. @Autowired (필드 주입)

public class 라면끓이기 {
    @Autowired
    private 냄비 냄비;
    @Autowired
    private 물 물;
    @Autowired
    private 라면 라면;
}

"냄비, 물, 라면이 있겠거니~" 하고 바로 사용하려는 것.

 

@Controller
public class RamyeonController {
    @Autowired
    private RamyeonService ramyeonService; // "알아서 있겠지~" 하고 사용
}

 

 

 

 

2. 생성자 주입 방식

public class 라면끓이기 {
    private final 냄비 냄비;
    private final 물 물;
    private final 라면 라면;
    
    // 이게 '생성자'!
    public 라면끓이기(냄비 냄비, 물 물, 라면 라면) {
        this.냄비 = 냄비;
        this.물 = 물;
        this.라면 = 라면;
    }
}

"라면 끓이기를 시작하기 전에 냄비, 물, 라면을 반드시 준비하고 시작하자!"

 

@Controller
@RequiredArgsConstructor  // final 필드에 대한 생성자를 자동 생성
public class RamyeonController {
    private final RamyeonService ramyeonService;
    private final WaterService waterService;
    
    // 생성자 주입 방식 생략 가능
    //public RamyeonController(RamyeonService ramyeonService, WaterService waterService) {
    //    this.ramyeonService = ramyeonService;
    //    this.waterService = waterService;
    //}
    
    @GetMapping("/ramyeon")
    public String cookRamyeon() {
        waterService.boilWater();
        return ramyeonService.cook();
    }
}

 

 

 

 

 

테스트코드 예시

// 필드 주입(@Autowired)을 사용한 경우 테스트하기 어려움
@Test
void 라면_테스트() {
    RamyeonController controller = new RamyeonController();
    // ramyeonService를 주입할 방법이 마땅치 않음...
}

 

// 생성자 주입을 사용하면 테스트가 쉬움
@Test
void 라면_테스트() {
    RamyeonService mockService = new MockRamyeonService(); // 테스트용 가짜 객체
    WaterService mockWater = new MockWaterService();
    RamyeonController controller = new RamyeonController(mockService, mockWater);
    // 테스트 실행...
}

 

 

 

 

 

생성자 주입의 장점

  • 필요한 것들이 다 있는지 처음부터 확실히 확인할 수 있음
  • 한번 세팅되면 실수로 바뀌지 않음 (final 키워드 덕분에)
  • 테스트하기가 더 쉬움

'자바 > 스프링, 스프링부트' 카테고리의 다른 글

JPA 영속성 컨텍스트  (0) 2025.02.06
@PathVariable, @RequestParam  (0) 2024.12.05
@RequestBody, @ResponseBody  (0) 2024.12.03
Controller  (0) 2024.12.02
스테레오타입 어노테이션(Stereotype Annotations)  (0) 2024.11.29