일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 컨테이너
- 시작하세요! 도커 & 쿠버네티스
- LIST
- 쿠버네티스
- container
- contatiner
- 멀티 쓰레드
- 제네릭스
- 쓰레드
- 인프런
- Kubernetes
- 시작하세요 도커 & 쿠버네티스
- 스레드 제어와 생명 주기
- java
- Collection
- 자바
- 동시성
- 스레드
- 자료구조
- 리스트
- 중급자바
- 실전 자바 중급 2편
- Docker
- 실전 자바 고급 1편
- Thread
- 알고리즘
- 도커
- 도커 엔진
- 김영한
- 오케스트레이션
- Today
- Total
쌩로그
final 키워드 (feat. 스프링 DI(의존성 주입) & 필드 변수 생성자주입) 본문
final 키워드 (feat. 스프링 DI(의존성 주입) & 필드 변수 생성자주입)
.쌩수. 2023. 5. 4. 00:37나는 어차피 잘 될 사람이다.
어차피 잘 될 것이고, 지금도 잘 되고있고, 과거도 잘 되어왔기에,,,
이전에 썻던 DI에 관한 글에서 final
키워드에 대한 생각을 정리하긴 했는데, 그 때는 인스턴스 필드에 final
을 주는 이유에 대해서, 값이 변경 되는 것을 막기 위해서 라고 생각했다.
이것도 물론 맞는 말인데, 코드에 대해서 의문점이 들었다.
@Component
public class OrderServiceImpl implements OrderService {
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
해당 코드에 오류가 없다. 그런데,
생성자 중 윗 줄을 하나 지웠다.
그런데 한 곳에서 뻘건 줄이 뜬다.
에러 메세지
Variable 'memberRepository' might not have been initialized
이렇게 나오는데,
이렇단다.
그리고 뻘건 줄 쪽에 final
키워드 지워봤다.
애매한데 그래도 에러는 없다.
final
이 없고, 생성자로 아무것도 넣어주지 않으면, null
을 허용할 수 있다는 의미인데, final을 다시 넣으면, 에러가 나왔다...
이건 단순히 스프링 보단 final
의 키워드에 대한 개념이 부족한 듯... 찾아봤다.
음.. 스프링보단 final
의 개념에 대해 한번 더 보게 되었다.
일단 final
을 선언하면, 변경이 불가능한(불변) 상태가 되며, 그렇기 때문에 선언시 초기화를 동시에 해주어야 한다.
그런데, 인스턴스 변수의 경우에는 생성자에서 초기화 되도록 할 수 있다고 한다.
즉 생성자의 매개변수로 final이 붙은 필드를 초기화할 수 있다.
(자바의 정석 3판 346페이지참고)
그래서
private final MemberRepository memberRepository = new MemberRepository();
이런식으로 선언과 동시에 초기화 해야하지만, DI(의존성 주입)을 통해서 스프링 컨테이너에 올라간 Bean
을 인스턴스 생성시 생성자 주입을 통해서 final
이 붙은 인스턴스 필드에 Bean객체를 주입해줄 수 있다.
그리고 번외로 생성자 주입을 해야,
변경 불가능한 불변성을 지키며, 혹여나 이후에 생길 변경으로 인한 문제를 예방할 수 있다.
-끝-
'Spring Project > Spring & Spring Boot' 카테고리의 다른 글
Transacitinal 오개념 바로잡기 (0) | 2023.11.19 |
---|---|
Spring Controller 계층에서 파일 입력받기 (3) | 2023.11.19 |
Mockito로 Test작성 시 given.willReturn에 void 적용할 때 (0) | 2023.07.23 |
Mapper를 사용할 때 필드명을 바꿔주는 것이 좋다. (0) | 2023.06.21 |
Spring에서의 DI (생성자 주입과 final) (0) | 2023.05.04 |