의존관계 자동주입

Spring Core Principles – Basics (김영한) 강의를 듣고 작성한 글입니다.

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90 %EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8

중독 주사

  • 건설자 주입
  • 수식어 세터
  • 필드 주입
  • 제네릭 메서드 주입

첫 번째 봄 빈 만들기 후 => 2. 중독 주사(Spring 컨테이너가 관리하는 Spring Bean에서만 작동).

생성자 주입

생성자를 통해 종속성(@Autowired)을 주입하는 방법

=> 생성자 호출 시 완벽한 한 번만 전화하다.

불변의 필수 의존성(배우가 변하지 않는 것처럼)

건설자 하나만 있으면 @Autowired를 생략해도 자동 주입(봄콩에 한함)


수정자 주입

세터~라고 불리는 필드 값 변경하다 수정자 방법(@Autowired)를 통해 종속성을 추가합니다.

=> 선택, 변화의 가능성(변수의 마지막 속성 제거)와의 종속성에 사용됩니다.


실행해보면 값이 잘 수신(잘 호출됨)된 것을 확인할 수 있습니다.


* @Autowired가 수정자 주입에 첨부되지 않는 한 Spring은 처음에 함수를 실행하지 않기 때문입니다.

함수를 따로 호출하지 않으면 반환값이 없습니다.

* 생성자 주입주사 대상 없는 경우 오류를 throw합니다.그대로 두십시오(파라미터 값이 없을 경우)

* 수정자 주입 Bean에 등록되지 않은 매개변수 주입 대상이 없는 경우에도 가능합니다(선택사항). => @Autowired(필수=false)부착하면 주사 대상이 없어도 작동합니다.

생성자 주입 및 수정자 주입 검색

Spring 라이프 사이클은 두 가지 주요 단계로 구성됩니다. 빈 등록 => 종속성 주입오전.

Bean 등록시 생성자가 호출되기 때문에 생성자 주입먼저 전화해~할 것이다 => 그러면 수정자 주입이 전화(의존성 주입 단계)


결과


생성자 주입 => 수정자 주입

생성자 주입과 수정자 주입을 함께 사용할 필요는 없습니다. 둘 다 동일한 종속성 주입 결과를 갖습니다.

생성자 주입 또는 수정자 주입을 사용합니다.

현장 주입

필드에 직접 스플래쉬하는 방법.


MemberRepository가 제대로 삽입되었는지 확인합시다(memberRepository 값이 덤프됨).


결과


잘 인쇄됩니다

필드 인젝션은 사용하기 매우 쉽지만 외부에서 변경할 수 없음테스트하기 너무 힘드네요…

또한 DI 프레임워크 없이 나는 아무것도 할 수 없다.(세터와 같은 것)

그래서 사용하지 않는 것이 좋습니다하다! (테스트 코드(@SpringBootTest)나 @건설 같은 장소에서만 특별한 목적을 위해)

예를 들어 테스트는 위의 OrderServiceImpl을 사용합니다. 회원 저장소붓다 더미 데이터 등으로 변경하여 테스트하고 싶습니다.추정

하지만 현장 주입 외부에서 변경하기 어렵기 때문에 나는 그것을 바꿀 수 없다. (생성자를 호출할 수 없고 세터가 없기 때문에)

현장 주입 – 테스트 코드

순수한 Java 코드(Spring이 로드되지 않은 상태)로 테스트를 실행한다고 가정해 보겠습니다.


테스트 코드

테스트를 실행하면 nullpointException수영하다

그 이유는 다음은 OrderServiceImpl입니다. 주문 생성 함수에서 memberRepository 및 discountPolicy에서 사용그럴지도 모른다


클래스 코드

이 테스트 코드는 스프링 없이 순전히 실행되기 때문에 새로운 OrderServiceImpl() 객체를 생성할 때 종속성이 삽입되지 않습니다.

따라서 memberRepository 및 discountPolicy가 포함되어야 합니다. 주입할 방법이 없습니다.

주입 세터를 만들어야 합니다.

세터 만들기


그 후 주사가 가능합니다.


그것은 잘 실행됩니다.

이런 필드 인젝션을 하면 세터를 따로 만들어야 하는 상황이 있습니다.하다..

그렇다면 수정 자 setter를 처음부터 만드십시오 …

이런 이유로 필드 인젝션을 사용하지 맙시다!

제네릭 메서드 주입


정상적인 방법으로 주사를 맞으십시오

여러 필드를 동시에 주입할 수 있습니다.

하지만 일반적으로 잘 사용하지 않습니다.

옵션 처리

주입 대상(주입할 생두)이 없는 상태에서도 작동해야 하는 경우가 있습니다.

@Autowired는 기본적으로 필요합니다=true때문에 주입 대상이 없으면 오류가 발생합니다.

주입 대상이 없을 때 옵션으로 처리하는 방법

  • @Autowired(필수=false) : 주입 대상이 없을 때 메서드를 호출할 수 없습니다.
  • org.springframework.lang.@Nullable : 자동 주입 대상이 없을 때 0이 입력됩니다.
  • 선택적<> : 자동 주입 대상이 없는 경우 선택 과목. 비어 있는 입력됩니다.


회원이 여기에 존재하지 않습니다 => 주입 대상이 없습니다.

결과


생성자를 삽입할 때 특정 필드에 대해 @Nullable 및 Optional을 사용할 수 있습니다.

생성자 주입을 선택하는 이유는 무엇입니까?

  • 불변성
    • 대부분의 종속성은 종속성 주입 후에 변경되지 않으므로 생성자 주입을 사용하여 변경될 가능성을 제거합니다. 독점적으로 설계된할수있다.
  • 생략
    • set 으로 수정자 주입의 경우 종속성 주입을 생략할 수 있습니다. 테스트에는 코드를 크래킹하고 주입해야 하는 종속성을 확인하는 작업이 포함됩니다.
    • 생성자 주입은 생성 시 종속성을 주입합니다. IDE는 주입할 값을 즉시 알고 있습니다(누락 가능성이 적음). 또한 누락된 경우 컴파일 오류가 발생합니다.
  • 마지막 키워드
    • 필드에서 final 키워드 사용 필드에 값을 할당또는 생성자에서만 값 할당할수있다.
    • 생성자를 주입할 때 종속성이 누락되는 실수(빨간색 선이 있는 컴파일 오류)를 방지할 수 있습니다.


DiscountPolicy에 대한 삽입 누락이 빨간색으로 표시됩니다(컴파일 오류).

옵션이 필요할 때 항상 생성자 주입과 때로는 수정자 주입을 선택하십시오. 필드 주입은 선택 사항입니다. X

롬복 신청 방법

build.gradle


코드 추가

코드 추가

다른 옵션

Lombok 사용 예 – @게터, @세터


롬복을 사용한다면 별도의 getter와 setter를 생성할 필요 없이 lombok을 호출하여 작성하면 됩니다(helloLombok.getName, helloLombok.setName).

Lombok 사용 예 – @RequiredArgs 생성자

LombokX 사용


나만의 생성자 만들기(OrderServiceImpl(memberRepository, discountPolicy))

롬복 – @RequiredArgsConstructor 사용


생성자를 작성하지 않아도 Lombok에서 자동 생성

@RequiredArgsConstructor는 최종으로 표시된 필드생성자를 통해 의존성 주입그렇습니다 (자동 생성자 생성 및 의존성 주입!! 코드를 작성해야 합니다X)

Command+F12를 눌러 함수의 메서드 및 필드 목록을 표시할 수 있습니다.


종속성 주입 생성자 롬복에 의해 자동으로 생성됨볼 수 있습니다

다시 말해서,

@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
    this.memberRepository = memberRepository;
    this.discountPolicy = discountPolicy;
}

이 코드를 작성할 필요가 없습니다.

(참고: 생성자가 있으면 @Autowired를 생략해도 자동으로 포함된다.)

필드에 final을 추가하고 주석(@RequiredArgsConstructor)만 사용하면 완료됩니다!!

검색에 일치하는 빈이 2개 이상 있는 경우

Bean을 부모로 조회 시 동시에 2개 이상의 Bean이 등록된 경우

예) DiscountPolicy 조회 시 FixDiscountPolicy와 RateDiscountPolicy가 모두 컴포넌트로 등록된 경우

=> 오류를 던지다두고

둘 다 구성 요소로 등록된 경우


ac.getBean(OrderServiceImpl.class) 여러 bean을 조회하기 때문에 선택할 수 없기 때문에 오류가 발생합니다.


Bean을 하위 유형으로 지정할 수 있지만 만약에 DIP가 위반되고 유연성이 감소합니다. 그리고 이름만 다를 뿐 똑같은 종류의 춘권이 2개 있으면 해결되지 않습니다.

해결

  • @Autowired 필드 이름
  • @한정자
  • @주요한

@Autowired 필드 이름 매칭

비어 있는 검색에서 @Autowired 1. 타입 매칭을 해보세요여러 빈을 가져올 때 2. 필드명과 파라미터명 추가 비교결과를 찾기 위해.


* 필드 주입용 한줄로 쓰기할 수 있어요.


@한정자

@Qualifier는 추가 구분 기호를 추가합니다. @Qualifier(“추가 별칭”)

자동 생성자 주입의 예


수정자 자동 주입의 예


@Qualifier(“mainDiscountPolicy”)로 @한정자 mainDiscountPolicy가 없으면 이름이 mainDiscountPolicy입니다. 톤을 찾아. (그래도 찾지 못하셨다면 NoSuchBeanDefinitionException 발생합니다.)

그러나 @Qualifier는 혼란스럽지 않으며 추가 구분 기호를 찾는 데 사용하는 것이 좋습니다.

등록이 비어 있는 경우 @Qualifier


@기본 사용

우선순위를 정하는 방법오전. 여러 빈이 일치하면 @Primary가 우선합니다.


RateDiscountPolicy의 우선순위를 지정합니다.


여러 개의 bean을 조회하더라도 우선순위 bean으로 반환되기 때문에 오류가 발생하지 않는다.

@Primary 대 @Qualifier

@Primary가 지정되면 지정하지 않아도 특정 빈만 검색하는데 @Qualifier는 주입할 때마다 @Qualifier에 추가되어야 한다.

사용된

주 데이터베이스와 하위 데이터베이스가 있는 경우 검색이 편리하도록 @Primary를 주 데이터베이스로, 하위 데이터베이스를 검색하려면 @Qualifier를 설정합니다.

우선 사항

@Primary는 기본처럼 작동하고 @Qualifier는 세부적으로 작동합니다. Spring은 @Primary보다 @Qualifier를 우선시합니다. 왜냐하면 자동보다는 수동이 좁은 범위 선택이 넓은 범위보다 우선순위가 높기 때문입니다.