DI 의존성 주입(Dependency Injection) 3가지 방법
의존성 주입 방식에는 대표적으로 3가지가 있다. Constructor(생성자),Setter,Field 타입이 있다.
1. 생성자 주입 (Constructor Injection) *권장
public class ExampleCase {
private final UserService userService;
private final MemberService memberService;
@Autowired
public ExampleCase(UserService userService, MemberService memberService) {
this.userService = userService;
this.memberService = memberService;
}
}
* Spring 4.3부터 단일 생성자를 가진 클래스는 @Autowired 주석을 생략할 수 있습니다. 이것은 약간의 편리함과 상용구 제거입니다.
2. 세터 주입 (Setter Injection)
public class ExampleCase{
private final UserService userService;
private final MemberService memberService;
@Autowired
public void setUserService(UserService userService){
this.userService = userService;
}
@Autowired
public void setMemberService(DrinkService memberService){
this.memberService = memberService;
}
}
3. 필드 주입 (Field Injection)
public class ExampleCase{
@Autowired
private UserService userService;
@Autowired
private MemberService memberService;
}
3가지중 스프링은 생성자 주입 방식을 권장한다.
필드 주입 방식으로 작성했을때 나타나는 경고 Field injection is not recommended.
생성자 주입 방식을 사용해야 하는 이유
https://www.baeldung.com/constructor-injection-in-spring
[Spring] 생성자 주입을 사용해야 하는 이유
인턴을 시작한 초기 단계에, Spring 프로젝트 코드 분석을 하다가 신기한 점을 발견해서 질문을 한 기억이 있습니다. Spring프로젝트에서 Controller를 작성할 때, 저는 항상 @Autowired 어노테이션을 사
programforlife.tistory.com
final 키워드로 선언된 변수는, 초기에 클래스 생성 시 반드시 초기값이 세팅되어야 하고, 변하지 않는 변수라는 것을 의미
field injection을 사용할 때에는 final 키워드를 사용할 수 없지만,
constructor injection을 사용할 때에는 final 키워드를 사용할 수 있다.
그렇기 때문에 immutable하게(변경 불가능하게) 사용할 수 있다. = 불변성을 지킴
Spring에서 Lombok으로 생성자 주입
@RequiredArgsConstructor
final이 붙거나 @NotNull 이 붙은 필드의 생성자를 자동 생성해주는 롬복 어노테이션
Lombok 어노테이션을 을 사용하여 모든 클래스의 필드(@AllArgsConstructor 사용) 또는 모든 final 클래스의 필드(@RequiredArgsConstructor 사용) 에 대한 생성자를 생성할 수 있다.
* 즉 의존성 주입을 생성자 방식으로 할때 final로 선언 후 해당 어노테이션을 붙여주기만 하면 돼서 코드가 간결해짐.
- Required 필수의
- Args(argument) 매개변수 : 함수를 이용할때 집어 넣는 값
- Constructor 생성자
-> 필수로 적어줘야하는 생성자를 대신해서 자동으로 생성해준다고 해석 가능
--> 코드가 간결해짐
@RequiredArgsConstructor를 사용하지 않으면 원래는 이렇게 생성자 주입을 해야한다.
@Service
public class BannerServiceImpl implements BannerService {
private BannerRepository bannerRepository;
private CommonFileUtils commonFileUtils;
@Autowired
public BannerServiceImpl(BannerRepository bannerRepository, CommonFileUtils commonFileUtils) {
this.bannerRepository = bannerRepository;
this.commonFileUtils = commonFileUtils;
}
@RequiredArgsConstructor 를 활용한 생성자 주입
@Service
@RequiredArgsConstructor
public class BannerServiceImpl implements BannerService {
private final BannerRepository bannerRepository;
private final CommonFileUtils commonFileUtils;
}