Enthusiasm! Enthusiasm!

의존관계 자동 주입(1) 본문

자바 스프링/스프링 핵심원리

의존관계 자동 주입(1)

열동 2023. 1. 9. 23:23

의존관계 주입의 종류

  1. 생성자 주입
  2. 수정자 주입(setter 주입)
  3. 필드 주입
  4. 일반 메서드 주입
  • 생성자 주입
    • 생성자를 통해서 의존관계를 주입 받는 방법, 생성자에 @Autowired 애노테이션을 붙혀주면 된다.
    • 생성자 호출 시점에 딱 1번만 호출 되는 것이 보장된다.
    • 불변, 필수의 의존관계에 사용
      • 불변: 한번 의존관계가 주입되면 주입된 값이 프로그램 종료시까지 바뀌지 않음. 주입된 값이 바뀌어서는 안되는 상황일때. 사용, 외부에서 데이터에 접근할 수 없어야 하며, 반드시 생성자 주입으로 딱 한번만 주입 되어야 한다.
      • 필수: private final과 같이 선언된 필드와 같이 반드시 값이 주입되어야 할 때 생성자 주입이 사용된다.
    • 생성자가 1개만 있으면 @Autowired를 생략해도 자동으로 생성자 주입이 된다.
  • 수정자 주입(setter주입)
    • setter메서드를 통해 의존 관계를 주입 받는 방법, setter 메서드 위에 @Autowired를 붙혀주면 된다.
    • 생성자 없이 setter 메서드만 있으면 주입 받을 수 있다.
    • 생성자와 setter메서드 둘 다 존재한다면 생성자가 먼저 주입 받는다. setter메서드 사이에서는 우선순위가 없다.
    • 선택,변경 가능성이 있는 의존관계에 사용
      • 변경: 중간에 이 인스턴스를 호출하여 강제로 바꿈(이렇게 사용될 일은 거의 없긴하다.) 
      • 선택 : 주입할 대상이 없어도 동작하게 만든다. @Autowired(required = false)를 달아주면 된다. 파라미터가 존재하지 않을 수도 있을 때 사용한다.
        • ex) memberRepository가 값이 없는 경우가 존재한다면 아래 코드처럼 사용
@Autowired(required = false)
        public void setMemberRepository(MemberRepository memberRepository) {
            this.memberRepository = memberRepository;
        }

 

                           

  • 필드 주입
    • 필드(선언된 변수)에 바로 의존관계를 주입 받는 방식
    • @Autowired private MemberRepository meberRepository
    • 순수 자바코드로 테스트를 하기가 힘들다. setter를 추가로 만들는게 아니면 한번 필드에 주입된 필드값을 바꿀 수가 없음 DI없이 테스트를 할 수 없다. setter를 추가로 만들꺼면 setter주입을 사용하는게 나음
    • 되도록이면 사용하지 않는게 좋다!!!!
  • 일반 메서드 주입
    • 일반 메서드를 통해 주입받는 방법
    • 한번에 여러 필드를 주입 받을 수 있다.
    • 생성자와 수정자를 통해 대체할 수 있어서 잘 쓰이지 않는다.
  • 옵션처리
    • 주입할 스프링 빈이 없어도 동작해야 할 때 사용
    • @Autowired(required=false) : 자동 주입할 대상이 없으면 수정자 메서드 자체가 호출 안됨
    • org.springframework.lang.@Nullable : 자동 주입할 대상이 없으면 null이 입력된다.
    • Optional<> : 자동== 주입할 대상이 없으면 Optional.empty 가 입력된다.

옵션 처리 3가지 예제

생성자 주입을 선택해야 하는 이유

1.불변

  • 대부분의 의존관계 주입은 한번 일어나면 애플리케이션 종료시점까지 의존관계를 변경할 일이 없다. 오히려 대부분의 의존관계는 애플리케이션 종료 전까지 변하면 안된다.
  • 수정자 주입을 사용하면, setXxx 메서드를 public으로 열어두어야 한다.누군가 실수로 변경할 수 도 있고, 변경하면 안되는 메서드를 열어두는 것은 좋은 설계 방법이 아니다.
  • 생성자 주입은 객체를 생성할 때 딱 1번만 호출되므로 이후에 호출되는 일이 없다. 따라서 불변하게 설계하기 용이하다.

2.테스트에 용이

  • 자바 코드 순수 테스트를 하는 경우 setter주입을 사용하면 해당 객체를 생성할때, 어떤 값들을 주입시켜야 하는지 한눈에 알 수 없고 테스트 전까지 컴파일 에러를 발생시키지 않는다.
  • 반면 생성자 주입을 사용하면, 해당 객체를 생성할때 값을 주입시키지 않으면 컴파일 에러가 발생하여 쉽게 의존관계를 파악할 수 있다.
  • 또한 생성자 주입을 사용하면 필드에 final 키워드를 사용할 수 있다. final 키워드를 사용하면 생성자에서 초기화 시키기 않으면 컴파일 에러가 발생하므로 생성자에서 값이 설정되지 않는 오류를 컴파일 단계에서 잡아줄 수 있다.
  • 수정자 주입을 포함한 나머지 주입 방식은 모두 생성자 이후에 호출되므로, 필드에 final 키워드를 사용할 수 없다. 오직 생성자 주입 방식만 final 키워드를 사용할 수 있다.

 

기본으로 생성자 주입을 사용하고, 필수 값이 아닌 경우에는 수정자 주입 방식을 옵션으로 부여하면 된다. 생성자 주입과 수정자 주입을 동시에 사용하면 된다. (사실 대부분이 불변이라 선택도 사용하는 경우가 별로 없다고 한다.)

 

가장 쉽게 오류를 찾는 방법은 컴파일 에러를 발생시키는 것이다. 컴파일 단계에서 오류를 잡을 수 있게 설계하자


롬복(Lombok)

  • Lombok 이란 Java 라이브러리로 반복되는 getter, setter, toString .. 등의 반복 메서드 작성 코드를 줄여주는 코드 다이어트 라이브러리 이다.
  • 롬복의 사용이유: 개발을 진행해보면, 대부분이 다 불변이고, 따라서 필드에 final 키워드를 사용하게 된다. 이 때 생성자도 만들어야 하고, 주입 받은 값을 대입하는 코드도 만들어야 하는 불편함을 해소하기 위해 사용

롬복 사용에제

        - 롬복 라이브러리를 다운 받은 뒤 애노테이션들을 이용하여 사용하면 된다.

        - 위와 같이 getter setter ToString 메서드를 만들지 않아도 롬복이 이를 만들어주어 위와 같이 메서드들을 사용할 수 있다.

 

  • @RequiredArgsConstructor
    • final이 붙어있는 필드들에 대해 자동으로 생성자를 만들어주는 롬복 어노테이션
    • 생성자가 한개일때 @Autowired를 생략해도 되므로 @RequiredArgsConstructor만 사용해도 생성자 주입이 된다.
    • 최종 결과 코드
@Component
@RequiredArgsConstructor
public class OrderServiceImpl implements OrderService{
	private final MemberRepository memberRepository;
    private final DiscountPolicy discountPolicy;
}

 

롬복을 사용하면 위 처럼 코드의 길이를 많이 줄일 수 있고, 새로운 필드가 생성되어도 선언만 하면 되고 나머지를 직접 수정해줄 필요가 없어진다.


이전 포스팅 - https://yulddong.tistory.com/13

 

컴포넌트 스캔

이 포스팅은 스프링 핵심원리 - 기본편(By Inflearn 김영한님) 강의 및 강의자료를 참고하여 작성하였습니다. 컴포넌트 스캔 기초 기존에는 설정정보에 @Bean을 사용하여 일일이 스프링 빈을 등록했

yulddong.tistory.com

 

다음 포스팅 - https://yulddong.tistory.com/15

 

의존관계 자동 주입(2)

이 포스팅은 스프링 핵심원리 - 기본편(By Inflearn 김영한님) 강의 및 강의자료를 참고하여 작성하였습니다. 조회 빈이 2개이상일때 현재까지는 같은 타입에 대해서 스프링 빈으로 등록할 클래스

yulddong.tistory.com


이 포스팅은 스프링 핵심원리 - 기본편(By Inflearn 김영한님) 강의 및 강의자료를 참고하여 작성하였습니다.

'자바 스프링 > 스프링 핵심원리' 카테고리의 다른 글

빈 생명주기 콜백  (0) 2023.01.11
의존관계 자동 주입(2)  (4) 2023.01.10
컴포넌트 스캔  (0) 2023.01.06
싱글톤 컨테이너  (0) 2023.01.05
스프링 빈 조회  (2) 2023.01.04
Comments