[SPRING] 인프런 스프링 기본편 강의 공부기록. 下 (완)
2022. 3. 7. 12:39ㆍJAVA
반응형
의존관계 자동 주입
크게 4가지로 분류한다
- 생성자 주입
- 수정자 주입(setter)
- 필드 주입
- 일반 메서드 주입
생성자 주입 :
@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;
}
}
- 생성자 호출시점에 딱 1번만 호출되는 것이 보장된다.
- 불변, 필수 의존관계에 사용
- 생성자가 하나일 때는 @Autowired 생략 가능
수정자 주입:
@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;
}
}
- 적용을 선택적으로 할 수 있음 (required = false)
- set메소드가 있으므로 runtime 내에 변경 가능
필드 주입:
@Component
public class OrderServiceImpl implements OrderService {
@Autowired
private MemberRepository memberRepository;
@Autowired
private DiscountPolicy discountPolicy;
}
- 간결하지만 외부에서 변경 불가능하므로 테스트하기가 어렵다
- DI 프레임워크에 강하게 의존한다
- 권장 안함 (인텔리제이에서도 쓰지말라고함)
- 테스트코드에서는 한번쯤 써도 괜찮음
일반 메서드 주입:
@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;
}
}
- 일반 메서드를 통해 주입 받을 수 있다
- 일반적으로는 사용하지 않음
옵션 처리
//호출 안됨
@Autowired(required = false)
public void setNoBean1(Member member) {
System.out.println("setNoBean1 = " + member);
}
//null 호출
@Autowired
public void setNoBean2(@Nullable Member member) {
System.out.println("setNoBean2 = " + member);
}
//Optional.empty 호출
@Autowired(required = false)
public void setNoBean3(Optional<Member> member) {
System.out.println("setNoBean3 = " + member);
}
- Member는 스프링 빈으로 등록되어있지 않다.
- setNoBean1() 은 (required=false) 이므로 호출 자체가 되지 않는다.
@Nullable, Optional은 스프링 전반에 걸쳐 지원된다. (ex. 생성자 자동 주입에서 특정 필드에만 사용하는 것 가능)
생성자 주입을 선택하라
최근에는 스프링을 포함한 DI 프레임워크 대부분이 생성자 주입을 권장한다.
1. 불변
- 연극이 시작되면, 배역을 맡은 배우는 바뀌지 않는다. 바뀌는 경우가 있다면 공연이 끝나고 다음 공연 사이에 일어나는 것이 정상. 꼭 바뀌어야 하는 프로그램이 있다면 설계를 다시 고민해야 한다.
- 수정자 주입을 사용하면 set~~~() 메서드가 public 으로 열려있는 문제가 있다
- 누군가 setter public 메서드를 사용할 수 있는 문제점
2. 누락
- 순수 자바코드로 유연하게 테스트 가능
- final 키워드를 사용해 의존관계 누락을 방지할 수 있다. (생성자 주입방법에서만 가능함)
컴파일 오류가 가장 쉽고 좋은 오류!
결론: 항상 생성자 주입을 사용하라. 꼭 필요하다면 수정자 주입도 선택 가능. 필드 주입은 쓰지 않는 것으로.
롬복과 최신 트렌드
build.gradle에 추가
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
// dependencies
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testCompileOnly 'org.projectlombok:lombok'
testAnnotationProcessor 'org.projectlombok:lombok'
preference - compiler - annotation processors - Enable annotation processing 활성화
@RequiredArgsConstructor - 생성자 자동생성. 필드주입처럼 써도 됨
최근 실무에서 가장 많이 쓰는 방식.
만약 조회되는 빈이 2개 이상이라면?
-> NoUniqueBeanDefinitionException 발생. 참 친절한 스프링...!
@Autowired 필드명 매칭이 필요하다.
2022-03-07 작성중
반응형
'JAVA' 카테고리의 다른 글
인스턴스화를 막기 위한 private 생성자 (2) | 2022.05.18 |
---|---|
[Spring + DB] 트랜잭션과 스프링 (0) | 2022.05.13 |
[SPRING] 인프런 스프링 기본편 강의 공부기록. 中 (2) | 2022.03.03 |
[SPRING] 인프런 스프링 기본편 강의 공부기록. 上 (0) | 2022.03.02 |
[SPRING] 인프런 스프링 입문 강의 공부기록. 12강 ~ (0) | 2022.02.28 |