티스토리 뷰

Spring

[Spring]생성자와 의존성 주입

minji_6119 2022. 12. 7. 08:48

1. @AllArgsConstructor / @NoArgsConstructor / @RequireArgsConstructor (생성자 자동완성 어노테이션)

@AllArgsConstructor

모든 변수를 사용하는 생성자를 자동완성 시켜주는 어노테이션

@AllArgsConstructor
public class Order {
    private String food;
    private int price;
    private String makers;

    /*@AllArgsConstructor를 사용하면 아래와 같은 생성자를 자동 생성할 수 있다.
    public Order(String food, int price, String makers) {
        this.food = food;
        this.price = price;
        this.makers = makers;
    }
    */
    }

@NoArgsConstructor

어떠한 변수도 사용하지 않는 기본 생성자를 자동완성 어노테이션이다.

@NoArgsConstructor
public class Order {
    private String food;
    private int price;
    private String makers;

    /*@NoArgsConstructor 사용하면 아래와 같은 생성자를 자동 생성할 수 있다.
    public Order() {

    }
    */
}

@RequireArgsConstructor

특정 변수만을 활용하는 생성자를 자동완성 시켜주는 어노테이션이다. 생성자의 인자로 추가할 변수에 @NonNull 어노테이션을 붙여서 해당 변수를 생성자의 인자로 추가할 수 있다. 아니면 해당 변수를 final로 선언해도 의존성을 주입받을 수 있다.

@RequireArgsConstructor
public class Order {
    @NotNull
    private String food;
    private final int price;
    private String makers;

    /*@RequireArgsConstructor 사용하면 아래와 같은 생성자를 자동 생성할 수 있다.
    public Order(String food, int price) {
        this.food = food;
        this.price = price;
    }
    */
}

@Builder(번외)
Builder 패턴이란 점증적 생성자 패턴과 자바빈즈 패턴의 단점을 보완하기 위해 사용되는 디자인패턴이다. @Builder 어노테이션을 사용하면 클래스 객체 생성시 Builder 패턴을 적용시켜준다. 모든 변수들에 대해 build하기를 원한다면 클래스 위에 @Builder를 붙이면 되지만, 특정 변수만을 build하기 원한다면 생성자를 작성하고 그 위에 @Builder 어노테이션을 붙여주면 된다.

Builder 패턴을 적용시 장점

  • 불필요한 생성자의 제거
  • 데이터의 순서에 상관없이 객체생성 가능
  • 명시적 선언으로 이해하기가 쉬우며 각 인자가 어떤 의미인지 알기 쉽다.
  • setter메서드가 없으므로 변경 불가능한 객체를 만들수있다.
  • 정보들을 다 받은 후에 한번에 객체를 생성하므로 객체일관성이 깨지지 않는다.
  • build()함수가 null인지 체크해주므로 검증이 가능한다.

2. 의존성 주입 방법

생성자 주입(Constructor Injection): 생성자를 통해 의존 관계를 주입하는 방법

@Service
public class UserService {

    private UserRepository userRepository;
    private PasswordEncoder passwordEncoder;

    @Autowired
    public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder) {
        this.userRepository = userRepository;
        this.passwordEncoder = passwordEncoder;
    }    
}

생성자가 의존성 주입되는 클래스 내에 1개만 존재할 경우 @Autowired 어노테이션을 생략할 수 있다.
생성자 주입을 이용하면 필드 객체에 final(더이상 수정 불가능) 키워드를 사용할 수 있으며, 컴파일 시점에 누락된 의존성을 확인할 수 있다.

@Service
@RequireArgsConstuctor
public class UserService {
    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;

}

주입 시킬 객체(UserRepository, PasswordEncoder)에 final 키워드를 붙임으로써 UserService가 스프링 컨테이너에 Bean으로 등록될 때 UserRespository와 PasswordEncoder를 주입시켜준다.

수정자 주입(Setter Injection): Setter를 통해 의존 관계를 주입하는 방법

@Service
public class UserService {

    private UserRepository userRepository;
    private PasswordEncoder passwordEncoder;

    @Autowired
    public setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }  

    @Autowired
    public serPasswordEncoder(PasswordEncoder passwordEncoder) {
        this.passwordEncoder = passwordEncoder;
    }   
}

주입받는 객체가 변경될 가능성이 있는 경우에 사용한다.

필드 주입(Field Injection): 필드에 바로 의존 관계를 주입하는 방법

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private PasswordEncoder passwordEncoder;
}

필드 주입은 외부에서 접근이 불가능하다는 단점이 존재한다. 또한, 필드 주입은 DI 프레임워크가 존재해야 하므로 프레임 워크와의 의존성이 강하게 결합된다. 따라서 애플리케이션의 구동에 무관한 테스트 코드를 작성하거나 불가피하게 설정해야할 경우를 제외하고 사용을 지양해야한다.

실제 개발 상황에서는 의존 관계의 변경이 필요한 경우는 드물다. 수정자 주입과 같이 수정의 가능성을 열어둔 상태로 개발을 진행하게 되면 유지 보수성이 떨어진다. 그러므로 의존 관계 주입시, 생성자 주입을 통해 변경의 여지를 두지 않고 불변성을 보장하는 것이 좋다.

생성자 주입을 사용할 경우의 장점

① 순환 참조 방지

-> 애플리케이션 구동시 객체의 생성 시점에서 에러(컴파일 에러)가 발생하므로 순환 참조 문제를 방지할 수 있다.

② 테스트 코드 작성 용이

-> 생성자 주입을 사용하면 컴파일 시점에 객체를 주입받아 테스트 코드를 작성할 수 있으며, 주입하는 객체가 누락된 경우 컴파일 시점에 오류를 발견할 수 있다

③ 객체의 불변성을 확보할 수 있으며, 객체의 변이를 방지한다.

-> 애플리케이션이 구동되어 @Component 어노테이션을 통해 Spring Bean으로 등록된 final 키워드를 가진 객체들은 객체 생성 이후 내부 상태가 변화하지 않는다.(read-only 메소드만 제공)

참고자료
참고자료2

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
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 31
글 보관함