1. Field Injection
의존성을 주입하고 싶은 필드에 @Autowired 어노테이션을 붙여주면 의존성이 주입된다.
1. 주입받으려는 빈의 생성자를 호출하여 빈을 찾거나 빈 팩토리에 등록
2. 생성자 인자에 사용하는 빈을 찾거나 만듦
3. 필드에 주입
@RestController
public class PostController {
@Autowired
private PostService postService;
}
2. Setter based Injection
setter메서드에 @Autowired 어노테이션을 붙여 의존성을 주입하는 방식.
1. 주입받으려는 빈의 생성자를 호출하여 빈을 찾거나 빈 팩토리에 등록
2. 생성자 인자에 사용하는 빈을 찾거나 만듦
3. 주입하려는 빈 객체의 수정자를 호출하여 주입
@RestController
public class PostController {
private PostService postService;
@Autowired
public void setPostService(PostService postService){
this.postService = postService;
}
}
3. Constructorbased Injection
생성자를 사용하여 의존성을 주입하는 방식
1. 생성자의 인자에 사용되는 빈을 찾거나 빈 팩토리에서 만든다.
2. 찾은 인자 빈으로 주입하려는 생성자를 호출한다.
객체가 생성되는 시점에 빈을 주입하여 의존성이 주입되지않아 발생할 수 있는 NullPointerException을 방지함
@RestController
public class PostController {
private final PostService postService;
public PostController(PostService postService){
this.postService = postService;
}
}
테스트 코드 생성자 주입 에러
마지막 생성자로 빈을 주입하게 되는 경우 테스트 코드일경우 에러가 나는데
주체가 Spring이 아닌 Jupiter가 되므로 @Autowired를 명시적으로 선언해주어야 jupiter가 Spring Container에게 빈주입을 요청할수 있게된다.
스프링 프레임워크에 경우 Spring Ioc가 컨테이너에 등록할 Bean들을 먼저 찾아서 보관하고있고
이후 생성자 주입을 요구할경울 적절한 Bean을 찾아 생성자주입을 수행한다.
테스트 프레임워크의 경우 생성자 매개변수관리를 Jupiter가 하기때문에 생성자 주입을 요구하는 경우 생성자 매개변수를 처리할 ParameterResolver를 찾아보지만 해당 빈은 스프링이 가지고있기때문에 처리하지 못하고 에러가 난다.
이런경우 @Autiwired 어노테이션을 달아 명시해주면 Jupiter가 스프링 컨테이너에게 요청하게 되어 정상적으로 빈주입을 받을수 있게 된다.
참조
https://unluckyjung.github.io/testcode/2021/08/21/Junit5-Need-AutowiredAnnotation/