[SpringBoot] @RequiredArgsConstructor 필요없는 소스 리팩토링 필드 주입 & 생성자 주입 차이 TIL
팀원 분이 저의 소스에 문제점을 지적해주었다. 그래서 그것을 앞으로 더이상 이상하게 사용하지 않고, 잘 쓰게끔 머릿 속에 저장 할 겸 이렇게 작성하게 되었다.
# 문제점 :
@RequiredArgsConstructor
@RequiredArgsConstructor(생성자 주입)의 어노테이션과 나는 소스 안에서
@Autowired
ResourceLoader resourceLoader;
@Autowired(필드주입)의 어노테이션을 같이 사용하고 있었다.
이것은 한마디로 같은 역할을 하는데, 두번 중복으로 쓰고 있다는 이야기다. 그래서
@RequiredArgsConstructor을 사용하면,
@Autowired 필드 주입은 사용할 필요 없고 그냥 final로만 적어주면 된다.
# 해결 :
@RequiredArgsConstructor
private final ResourceLoader resourceLoader;
private final ResourceLoader resourceLoader; 만 해주면 생성자 주입이 된다.
물론 @RequiredArgsConstructor을 안사용하면
@Autowired의 필드 주입으로
ResourceLoader resourceLoader을 사용하면 됨. 그렇지만...
# 문제점2 :
이렇게 주입 할 때 필드 주입은 선호 하지 않는다고 한다.
예를 들면, PdfService안에서 UserService내용을 가져와야하고, 그리고 UserService 안에서 PdfService의 내용을 가져와야할 때, 크로스 느낌.
=> 이것이 순환 참조 방지. 즉 객체 의존성을 추가하다 보면 순환 참조 문제가 발생할 수 있다.
순환 참조는 A -> B를 참조하면서, B -> A를 참조하는 경우 문제가 발생함.
이렇게 서로 필드 주입을 하면은, 순환 참조로 인해 서버가 죽는다고함.
그래서 이런식으로 사용할 때는 @Autowired를 사용하지말고, 생성자 주입 @RequiredArgsConstructor을 사용하자.
※ 참고
@RequiredArgsConstructor 어노테이션을 안쓰면,
private final ResourceLoader resourceLoader;
public PdfServiceImpl(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
를 사용하면 된다.
=
아래와 같은 의미
@RequiredArgsConstructor
public class boardImpl implements boardService {
private final ResourceLoader resourceLoader;
}