final 키워드 (feat. 스프링 DI(의존성 주입) & 필드 변수 생성자주입)

김성수·2023년 4월 23일
0

스프링 및 부트

목록 보기
9/9

나는 어차피 잘 될 사람이다.

어차피 잘 될 것이고, 지금도 잘 되고있고, 과거도 잘 되어왔기에,,,


이전에 썻던 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객체를 주입해줄 수 있다.

그리고 번외로 생성자 주입을 해야,
변경 불가능한 불변성을 지키며, 혹여나 이후에 생길 변경으로 인한 문제를 예방할 수 있다.


-끝-

profile
쌩수 Git >> https://github.com/SsangSoo?tab=repositories

0개의 댓글