본문 바로가기

JAVA

[SPRING] 의존관계 주입 DI

1. 의존관계 주입 방법

  • 생성자 주입
  • 수정자 주입(setter 주입)
  • 필드 주입
  • 일반 메서드 주입

생성자 주입

클래스 생성자를 통해 의존 관계를 주입 받는 방법입니다. 생성자로만! 

  • 생성자 호출 시점에 최초 1번만 호출된다.
  • "불변, 필수" 의존관계에 사용
  • 오직 생성자 주입 방식에만 final 키워드를 사용할 수 있다.
  • 생성자 주입을 권장 
  • 필수 값이 아닐 경우, 수정자 주입 방식Optional<>을 사용한다. 생성자, 수정자 방식 동시에 사용 가능
@Component
public class MemberServiceImpl implements MemberService {

private final MemberRepository memberRepository;

    @Autowired
    public MemberServiceImpl(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }
}

 

수정자 주입

setter 필드의 값을 변경하는 수정자 메서드를 통해 의존 관계를 주입 합니다.

  • "선택, 변경" 가능성이 있는 의존관계에서 사용
  • 자바 빈 프로퍼티 규약의 수정자 메서드 방식을 사용하는 방법

선택적이란

@Autowired 의 기본 동작은 주입할 대상이 없으면 오류를 반환합니다. 주입할 대상이 없어도 동작하게 하려면 아래와 같이 설정 합니다.

@Autowired(required = false)

 

@Component
public class OrderServiceImpl implements OrderService {

    private MemberRepository memberRepository;
    private DiscountPolicy discountPolicy;

	@Autowired
    void setMemberRepository(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }
	@Autowired
    void setDiscountPolicy(DiscountPolicy discountPolicy) {
        this.discountPolicy = discountPolicy;
    }
}

 

필드 주입 

이름 그대로 필드에서 바로 의존관계를 주입합니다.

  • 코드가 간결하지만, 외부에서 변경하기가 불가능해서 테스트하기 힘들다는 단점이 있다.
  • 최근에는 사용하지 않는다.
  • 테스트 코드에서만 사용하자
@Component
public class OrderServiceImpl implements OrderService {

    @Autowired private MemberRepository memberRepository;
    @Autowired private DiscountPolicy discountPolicy;
}

 

일반 메서드 주입

일반 메서드(아무 이름)를 통해서 의존관계 주입합니다.

잘 사용하지 않습니다.

 

@Component
public class OrderServiceImpl implements OrderService {

    private MemberRepository memberRepository;
    private DiscountPolicy discountPolicy;

    public void Init(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
        this.memberRepository = memberRepository;
        this.discountPolicy = discountPolicy;
    }
}

2. 옵션 처리

  • @Autowired(required = false) : 자동 주입할 대상이 없으면 수정자 메서드 자체가 호출이 되지 않는다.
  • @Nullable : Null을 반환
  • Optional<> : Optional.empty를 반환
        @Autowired(required = false)
        public void setNoBean1(Member noBean1) {
            System.out.println("member = " + noBean1);
        }
        @Autowired
        public void setNoBean2(@Nullable Member noBean2) {
            System.out.println("member = " + noBean2);
        }
        @Autowired
        public void setNoBean3(Optional<Member> noBean3) {
            System.out.println("member = " + noBean3);
        }

 

3. Lombok 라이브러리 사용

롬복 라이브러리를 사용시 어노테이션으로 자동으로 생성자 로직을 작성할 필요 없이 생성자 주입 방법을 사용 할 수 있습니다.

@RequiredArgsConstructor 기능을 사용하면 final이 붙은 필드를 모아서 자동으로 생성자를 생성해줍니다.

 

@Component
@RequiredArgsConstructor
public class OrderServiceImpl implements OrderService {

    private final MemberRepository memberRepository;
    private final DiscountPolicy discountPolicy;
}

 

build.gradle

 

configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}

dependencies {
	compileOnly 'org.projectlombok:lombok'
	annotationProcessor 'org.projectlombok:lombok'

	testCompileOnly 'org.projectlombok:lombok'
	testAnnotationProcessor 'org.projectlombok:lombok'
}

4. Bean이 여러개 일때 해결 하는 방법 

2023.06.19 - [JAVA] - [SPRING] DI시 중복 Bean 오류 해결 방법

 

[SPRING] DI시 중복 Bean 오류 해결 방법

1. 조회 대상 빈이 2개 이상일 때 해결방법 @Autowired 필드 명 매칭 @Quilifier -> @Quilifier 끼리 매칭 -> 빈 이름 매칭 @Primary 사용 @Autowired 필드 명 매칭 @Autowired 가 여러 개일 때 구체 클래스의 명으로 변

bakssse.tistory.com