목표
1. 생성자, setter, 필드, 일반 메서드. 이렇게 의존관계 주입 방법 4가지를 배운다. 각 방법의 특징을 기억하자.
2. 의존관계 주입을 옵션처리 하는 방법을 배운다.
'의존관계 자동 주입' 목차
1. 다양한 의존관계 주입 방법 (이번 포스팅)
2. 옵션 처리
3. 생성자 주입을 선택해라!
4. 롬복과 최신 트랜드
5. 조회 빈이 2개 이상 - 문제
6. @Autowired 필드 명, @Qualifier, @Primary
7. 애노테이션 직접 만들기
8. 조회한 빈이 모두 필요할 때, List, Map
9. 자동, 수동의 올바른 실무 운영 기준
1. 다양한 의존관계 주입 방법
1) 생성자 주입
이름 그대로 생성자를 통해 의존 관계를 주입 받는 방법이다. 지금까지 해온 생성자에 @Autowired 를 붙이는 방식이다.
특징
* 생성자 호출시점에 딱 1번만 호출되는 것이 보장된다.
* 불변, 필수 의존관계에 사용한다.
# 여담 - 이렇게 생성자 주입으로 의존관계를 세팅하면 좋은 이유?
스프링 빈을 생성할 때 생성자를 호출하니까. 이 시점에 의존관계 주입을 1번 딱 세팅하고 시작하고 싶은 것이다.
생성자 주입은 (빈 등록할 때 생성자를 호출하니까) 빈 등록과 의존관계 주입이 같이 일어난다.
개발할 때는 불변의 범위를 확실히 잡고가는 것이 중요하다.
# 여담 - 웬만하면 생성자에는 값을 다 채워 넣어야 한다고 생각하는게 관례다.
따로 생성자에 null을 허용한다는 얘기가 없으면, 비워두지 말고 값을 꼭 넣자.
[ 중요 ]
스프링 빈의 생성자가 1개인 경우, 생성자에 @Autowired 를 붙이지 않아도 생성자를 통해 의존관계가 주입된다!
아래 두 코드는 똑같이 생성자 주입으로 의존관계가 주입된다.
2) 수정자 주입(setter 주입)
필드 값을 변경하는 setter 메서드를 통해 의존관계를 주입하는 방법이다.
setter 메서드는 변수명 앞에 set을 붙이는 것이 관례다. 아래 처럼 setter 메서드를 만들고 @Autowired를 붙인다.
특징
* 선택, 변경 가능성이 있는 의존관계에 사용한다. (사실 거의 변경할 일은 드물다)
단, setter로 주입하니까. private MemberRepository 변수에는 final(상수)를 붙이면 안된다.
[ 참고 ]
@Autowired 의 기본 동작은 주입할 대상이 없으면 오류가 발생한다.
주입할 대상이 없어도 동작하게 하려면 @Autowired (required = false)로 지정하면 된다.
[ 참고 ] 자바빈 프로퍼티 규약
setXxx, getXxx 형태의 메서드로 필드 값을 수정하거나 읽자는 규약이다. 직접 필드값을 변경 하지 말자는 것이다.
3) 필드 주입
이름 그대로 필드에 @Autowired를 붙이면 의존관계를 빡 주입한다.
하지만 필드 주입을 권장하지 않는다. 안티패턴이다.
특징
* 코드가 간결해서 많은 개발자들을 유혹하지만 외부에서 변경이 불가능해서 테스트 하기 힘들다는 치명적인 단점이 있다.
* DI 프레임워크가 없으면 아무것도 할 수 없다. 순수한 자바코드로 제대로 테스트 할 수 없다.
* 애플리케이션의 실제 코드와 관계 없는 테스트 코드에서는 사용할 수도 있다.
4) 일반 메서드 주입
일반 메서드를 통해서 주입 받을 수 있다.
특징
* 한번에 여러 필드를 주입 받을 수 있다.
* 일반적으로 잘 안 쓴다.
[ 참고 ]
어쩌면 당연한 이야기이지만 의존관계 자동주입은 스프링 컨테이너가 관리하는 스프링 빈이어야 동작한다.
2. 옵션 처리
주입할 스프링 빈이 없어도 동작해야 할 때가 있다. 자동 주입 대상을 옵션으로 처리하는 방법 3가지를 알아보자.
Member 클래스는 스프링 빈이 아니다. 스프링 빈이 아닌 것을 @Autowired 하면, 자동 주입할 대상이 없는 상황인 것이다.
이 때 스프링 컨테이너를 생성해서 빈 등록을 시도해보자.
아래의 자동 주입 대상을 옵션으로 처리하는 방법을 사용하면 에러 없이 테스트가 성공한다.
1) @Autowired (required = false)
@Autowired 는 기본으로 자동주입 대상이 없으면 에러를 낸다. 기본값이 (required = true) 이다.
(required = false) 의미 : "자동 주입할 대상이 없으면(== 의존관계가 없으면), 수정자 메서드 자체를 호출하지 않는다. "
2) @Nullable
자동주입할 대상이 없으면 null이 입력된다.
3) 자바8의 Optional<>
자동주입할 대상이 없으면 Optional.empty 가 입력된다.
스프링 빈이 아닌 것을 @Autowired 할 때, 자동 주입 대상을 옵션으로 처리하는 코드
public class AutowiredTest { /** 의존관계 옵션 처리 */
@Test
void AutowiredOption(){
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(TestBean.class);
}
static class TestBean{
@Autowired(required = false)
public void setNoBean1(Member nobean1){
System.out.println("nobean1 = " + nobean1);
}
@Autowired
public void setNoBean2(@Nullable Member nobean2){
System.out.println("nobean2 = " + nobean2);
}
@Autowired
public void setNoBean3(Optional<Member> nobean3){
System.out.println("nobean3 = " + nobean3);
}
}
}
[ 참고 ]
Optional<> 과 @Nullable은 스프링 전반에 전부 지원되는 기능이다.
다음 강의에서는 생성자 주입을 선택해야 하는 이유를 배운다.
공부 내용 출처 : 스프링 핵심 원리 기본편
'프로그래밍 > Spring Basic' 카테고리의 다른 글
16. 조회할 빈이 2개 이상일 때의 문제 해결하기 (0) | 2021.12.27 |
---|---|
15. 생성자 주입을 선택해야하는 이유와 롬복 (0) | 2021.12.27 |
13. 컴포넌트 스캔의 필터와 빈 이름 중복 (0) | 2021.12.25 |
12. 컴포넌트 스캔과 의존관계 자동 주입 시작하기 (0) | 2021.12.25 |
11. @Configuration과 싱글톤 (0) | 2021.12.24 |