4. 의존 자동 주입
@Autowired를 이용한 의존 자동 주입
지금까지 설정코드에서 직접 의존관계를 주입했었다, 이번 장에서는 @Autowired를 이용한 의존 자동 주입에 대하여 알아보자.
@Autowired를 사용하면 의존 객체를 명시하지 않아도 스프링이 필요한 의존 객체를 자동으로 주입 해준다.
@Bean
public MemberDao memberDao(){
return new MemberDao();
}
@Bean
public ChangePasswordService changePwdSvc(){
ChangePasswordService pwdSvc = new ChangePasswordService();
pwdSvc.setMemberDao(memberDao());
return pwdSvc;
}
@Bean
public MemberDao memberDao(){
return new MemberDao();
}
@Bean
public ChangePasswordService changePwdSvc(){
ChangePasswordService pwdSvc = new ChangePasswordService();
return pwdSvc;
}
1번 코드의 경우 pwdSvc.setMemberDao(memberDao());를 통해 의존관계를 직접 주입 했지만,
2번 코드 처럼 자동 주입 기능을 사용하면 의존 객체를 직접 명시하지 않아도 스프링이 주입을 해준다.
@Autowired
private MemberDao memberDao;
자동 주입은 의존을 주입할 대상에 @Autowired 애노테이션을 붙이기만하면 된다.
@Autowired를 이용한 자동 주입 방법
의존관계 주입에는 크게 4가지 방법이 있다.
- 생성자 주입
- 수정자 주입(setter 주입)
- 필드 주입
- 일반 메서드 주입
▽ 자세히 보기
의존관계 주입에는 크게 4가지 방법이 있다.
- 생성자 주입
- 수정자 주입(setter 주입)
- 필드 주입
- 일반 메서드 주입
생성자 주입
- 생성자를 통해서 의존 관계를 주입 받는 방법
- 특징
- 생성자 호출 시점에 딱 1번만 호출되는것을 보장
- 불변, 필수 의존 관계 사용
@Component
public class OrderServiceImpl implements OrderService {
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
@Autowired // 생략 가능
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
}
생성자가 하나 일때는 @Autowired를 생략 할 수 있다.
수정자 주입(setter 주입)
- setter라 불리는 필드의 값을 변경하는 수정자 메서드를 통해서 의존관계를 주입하는 방법이다.
- 특징
- 선택, 변경 가능성이 있는 의존관계에 사용
- 자바빈 프로퍼티 규약의 수정자 메서드 방식을 사용하는 방법이다.
@Component
public class OrderServiceImpl implements OrderService {
private MemberRepository memberRepository;
private DiscountPolicy discountPolicy;
@Autowired
public void setMemberRepository(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
@Autowired
public void setDiscountPolicy(DiscountPolicy discountPolicy) {
this.discountPolicy = discountPolicy;
}
}
- @Autowired의 기본 동작은 주입할 대상이 없으면 오류가 발생한다.
- 주입할 대상이 없어도 동작하게 하려면 @Autowired (required = false)로 지정하면된다.
필드 주입
- 이름 그래도 필드에서 바로 주입하는 방법
- 특징
- 코드가 간결하지만 외부에서 변경이 불가능해서 테스트 하는데 어려움이 있다.
- DI 프레임워크가 없으면 아무것도 할 수 없다.
따라서 필드 주입은 사용하지 말자!
@Component
public class OrderServiceImpl implements OrderService {
@Autowired
private MemberRepository memberRepository;
@Autowired
private DiscountPolicy discountPolicy;
}
일반 메서드 주입
- 일반 메서드를 통해서 주입 받을 수 있다.
- 특징
- 한번에 여러 필드를 주입 받을 수 있다.
- 잘 사용하지 않는다.
@Component
public class OrderServiceImpl implements OrderService {
private MemberRepository memberRepository;
private DiscountPolicy discountPolicy;
@Autowired
public void init(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
}
일치하는 빈이 없거나 2개 이상인 경우
@Autowired 애노테이션을 적용한 대상이 일치하는 빈이 없는 경우 오류가 발생한다.
@Bean
public MemberPrinter memberprinter1{
return new MemberPrinter()
}
@Bean
public MemberPrinter memberprinter2{
return new MemberPrinter()
}
반면에 위와 같이 일치하는 빈이 2개 이상인 경우 마찬가지로 오류가 발생한다.
위와 같은 경우 우리는 @Qualifer 애노테이션을 사용한다.
@Qualifer 애노테이션을 이용한 의존 객체 선택
@Qualifer를 이용해 @Qualifer 끼리 매칭 시킬수 있다.
@Bean
@Qualifier("printer1")
public MemberPrinter memberprinter1{
return new MemberPrinter()
}
@Bean
@Qualifier("printer2")
public MemberPrinter memberprinter2{
return new MemberPrinter()
}
코드와 같이 @Qualifer를 이용해 이름을 지정해주고 해당 이름을 바탕으로 의존 객체를 설정할 수 있다.
@Autowired 애노테이션 필수 여부 정하기
일반적으로 매칭되는 bean이 존재하지 않으면 Exception이 발생한다, 이를 무시하고 반드시 주입을 안해도 되는 경우 다음 방법을 통해 필수 여부를 설정할 수 있다.
- @Autowired(required = false)
- 빈이 존재하지 않으면 자동 주입을 하지 않는다
- Optional
- 빈이 존재하지 않으면 값이 없는 Optional 값을 전달한다.
- @Nullable
- 존재하지 않으면 null값을 전달한다.
자동주입과 수동주입
설정 클래스에서 수동으로 의존을 주입했는데, 자동 주입 대상이 되면 어떻게 될까?
-> 자동 주입을 통해 일치하는 빈을 주입한다.
자동 의존 주입을 사용하자
'Java , Spring > Spring' 카테고리의 다른 글
스프링 MVC 1 - 서블릿 servlet (2) (0) | 2023.07.02 |
---|---|
초보 웹 개발자를 위한 스프링 5 프로그래밍 입문 - 5장 컴포넌트 스캔, 6장 빈 라이프사이클과 범위 (0) | 2023.05.19 |
초보 웹 개발자를 위한 스프링 5 프로그래밍 입문 - 2장, 3장 (0) | 2023.05.16 |
빈 스코프 (0) | 2023.05.07 |
빈 생명주기 콜백 (0) | 2023.05.05 |
댓글