@Autowired
@Autowired란 스프링 컨테이너에 등록한 빈에게 의존 관계를 자동으로 주입하기 위해 사용되는 어노테이션입니다.
스프링 컨테이너에 빈들을 모두 등록한 후에, 스프링 컨테이너는 @Autowired 어노테이션이 붙은 생성자, 필드 등을 스캔하고, 해당하는 빈을 찾아 의존성을 자동으로 주입합니다.
생성자 주입 ⭐권장⭐
@Component
public class ControllerClass {
private final ServiceClass serviceClass;
@Autowired
public ControllerClass(ServiceClass serviceClass) {
this.serviceClass = serviceClass;
}
}
- 객체 생성 시점에서 생성자를 통해 의존 관계를 주입받는 방식입니다. 때문에 딱 1번만 호출하는 것이 보장되고 필수 의존 관계인 경우 사용됩니다.
- 필드에 final 키워드를 사용할 수 있게되어 불변성을 보장해줍니다. 이는 코드의 안정성과 신뢰성을 높여줍니다.
- 객체의 생성과 의존성이 주입이 동시에 이루어지기 때문에, 객체가 완전히 초기화된 상태에서 사용할 수 있습니다.
- 생성자가 단 1개만 있으면 @Autowired를 생략해도 자동 주입됩니다.
수정자 주입
@Component
public class ControllerClass {
private ServiceClass serviceClass;
@Autowired
public void setServiceClass(ServiceClass serviceClass) {
this.serviceClass = serviceClass;
}
}
- 필드 값을 변경하는 setter 메서드를 통한 의존 관계 주입하는 방법입니다.
- 때문에 선택적인 의존성이나 변경 가능성이 있는 의존 관계에 사용됩니다.
- 의존성 주입이 객체 생성 후에 이루어지기 때문에 일부 필드가(어노테이션이 부여되지 않아) null일 수 있습니다.
필드 주입
@Component
public class ControllerClass {
@Autowired
private ServiceClass serviceClass;
}
- 생성자나 수정자를 사용하지 않고 필드에 바로 의존성을 주입하는 방식입니다.
- 의존성 주입이 객체 생성 후에 이루어지기 때문에 일부 필드가(어노테이션이 부여되지 않아) null일 수 있습니다.
- 외부에서 의존성을 변경하기 어려워, 테스트하기 어려울 수 있습니다. 이 경우 private 필드에 의존성을 주입하기 위해서는 Reflection을 사용해주어야 합니다.
💡생성자 주입을 권장하는 이유
수정자 주입과 필드 주입은 선택적인 의존성이나 동적인 의존성 변경이 필요한 경우에 유용할 수 있습니다. 하지만 필드 주입인 경우 Reflection을 사용해야 하고, 객체 초기화 과정이 명확하지 않아 문제를 야기할 수 있습니다.
생성자 주입은 객체의 불변성과 명시적인 의존성 표현을 제공하고, 테스트 용이성과 순환 의존성 방지에 도움을 줍니다.
💡Lombok을 통한 생성자 주입⭐
Lombok 라이브러리를 사용하면 다음 코드와 같이 생성자를 만들고 주입하는 코드를 작성하는 번거로움을 줄일 수 있습니다.
@Component
@RequiredArgsConstructor
public class ControllerClass {
private final ServiceClass serviceClass;
/ ...
}
의존성 주입할 Bean 없이도 정상 처리하기
의존성을 주입할 때 주입할 Spring Bean이 없으면 오류가 발생합니다. 주입할 Bean이 없을 때에도 예외를 방지하고 정상적으로 처리하기위한 방법은 다음과 같습니다.
- Optional<>
- Optional은 값을 감싸는 래퍼(Wrapper) 클래스로, null이나 null이 아닌 값을 감싸서 NPE(NullPointerException)를 발생하지 않게합니다.
- 의존성을 Optional로 감싸서 의존성이 없어도 Null 대신 Optinal.empty()를 반환하게 합니다.
- @Autowired(required = false)
- required 속성을 false로 설정하면 의존하는 빈이 없는 경우에 수정자 메서드 자체가 호출되지 않습니다.
- 만약 필드에 주입하는 경우 null로 주입되게 됩니다.
- @Nullable
- 이를 부여한 어노테이션은 null 일 수 있다는 것을 명시한 것입니다.
- 의존성이 없을 경우에도 null로 주입되게 됩니다.
// Optional.empty 호출
@Autowired
public void setNoBean1(Optional<Member> member) {
System.out.println("setNoBean3 = " + member);
}
// 호출 안됨
// true면 찾을 수 없다고 오류가 뜬다.
@Autowired(required = false)
public void setNoBean2(Member member) {
System.out.println("setNoBean1 = " + member);
}
// null 호출
@Autowired
public void setNoBean3(@Nullable Member member) {
System.out.println("setNoBean2 = " + member);
}
@Qualifier/ @Resource / @Inject
@Autowired, @Qualifier, @Resource, @Inject은 스프링에서 의존성 주입을 위해 사용되는 어노테이션입니다.
@Autowired
- @Autowired 어노테이션은 스프링에서 의존성을 자동으로 주입할 때 사용됩니다.
- 기본적으로 타입을 기준으로 주입할 빈을 선택합니다.
- 여러 개의 동일한 타입의 빈이 존재할 경우에는 추가적인 방법을 사용하여 어떤 빈을 주입할지 명시해야 합니다.
@Qualifier
- @Qualifier 어노테이션은 @Autowired와 함께 사용되어 어떤 빈을 주입할지 구분할 때 사용됩니다.
- 동일한 타입의 빈이 여러 개일 경우, @Qualifier와 함께 사용하여 빈의 이름 또는 구분자를 지정합니다.
- 필드, 생성자, 수정자 메서드에 적용할 수 있습니다.
@Autowired
@Qualifier("specificBean")
private MyBean myBean;
@Resource
- @Resource 어노테이션은 JSR-250 표준 스펙에서 제공하는 어노테이션으로 주입할 빈을 이름을 기준으로 선택합니다.
- 기본적으로 이름에 해당하는 빈이 존재하지 않을 경우 타입을 기준으로 빈을 찾습니다.
- 필드, 생성자, 수정자 메서드에 적용할 수 있습니다.
- @Qualifier와 유사한 기능을 수행합니다.
@Resource("specificBean")
private MyBean myBean;
@Inject
- @Inject 애노테이션은 JSR-330 표준 스펙에서 제공하는 의존성 주입 어노테이션으로 @Autowired와 유사한 역할을 수행합니다.
- @Inject는 스프링 프레임워크에 종속되지 않는 자바 표준 어노테이션입니다.
- @Autowired와 다른 차이점은 @Inject는 required 속성을 제공하지 않습니다.
- 필드, 생성자, 수정자 메서드에 적용할 수 있습니다.
@Inject("specificBean")
private MyBean myBean;
위 어노테이션들은 의존성 주입을 위해 사용되며, 주입할 빈을 선택하고 명시하는 방법에 차이가 있습니다.
예를 들어, @Autowired와 @Qualifier를 함께 사용하여 특정 빈을 주입하거나, @Resource를 사용하여 이름을 기준으로 주입할 빈을 선택할 수 있습니다. @Inject는 스프링 프레임워크에 종속되지 않는 자바 표준 어노테이션이지만, 사용법은 @Autowired와 유사합니다.
'Spring Framework' 카테고리의 다른 글
Spring 빈 생명주기( Bean Life Cycle ) (0) | 2022.08.24 |
---|---|
Spring 빈 스코프 ( Bean Scope ) (0) | 2022.08.23 |
Spring 빈(Bean) 등록 방법 ( XML, Annotation, Java 설정 클래스 ) (0) | 2022.08.20 |
Spring IoC 컨테이너 계층구조 및 구성(웹 어플리케이션) (0) | 2022.08.20 |
Spring 스프링 컨테이너(IoC 컨테이너)와 빈(Bean) (0) | 2022.08.20 |