AR삽질러

Spring 의존관계자동주입 - 의존관계주입방법(13) 본문

JAVA/Spring

Spring 의존관계자동주입 - 의존관계주입방법(13)

아랑팡팡 2023. 8. 21. 18:00
728x90

의존관계 주입방법

1. 생성자주입

2. 수정자주입(setter주입)

3. 필드주입

4. 일반 메서드주입

 

생성자주입(Constructor Injection)

 - 의존관계가 필수적일때 객체 생성 시점에서 의존관계를 한번에 주입 받는다.(불변, 필수 의존관계)

@Component
public class OrderServiceImpl implements OrderService{
	private final MemberRepository memberRepository;
    private final DiscountPolicy discountPolicy;
    
    @Autowired
    public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy){
    	this.memberRepository = memberRepository;
    	this.discountPolicy = discountPolicy;
    }
}

OrderServiceImpl

 - @Component 애노테이션이 붙은 클래스가 스프링빈으로 관리되고 스프링 컨테이너가 이 클래스의 인스턴스를 생성하고 관리하게 된다.

 - 두개의 필드는 OrderServiceImpl이 동작하기 위해 필요한 의존성으로 final키워드가 붙어 해당 필드가 한번 설정된 후에 변경될 수 없도록 만들어 불변성을 확보한다.

 - @Autowired 애노테이션 을 붙여 해당 생성자에 의존성 주입이 필요하다는 것을 스프링에 알리고 스프링은 해당 타입의 빈을 찾아서 주입한다.

 

수정자주입(Steer Injection)

 - 의존관계가 선택적이거나 변경가능성이 있을 때 사용하는 방식으로 객체 생성이후 Setter메서드를 통해 의존관계를 주입받는다.(선택, 변경 가능성이 있는 의존관계)

@Component
public class OrderServiceImpl implements OrderService{
	private MemberRepository memberRepository;
    private DiscountPolicy discountPolicy;
    
    @Autowired
    public void setMemberRepository (MemberRepository memberRepository){
    	this.memberRepository = memberRepository;
    }
    
    @Autowired
    public void setDiscountPolicy (DiscoutPolicy discountPolicy){
    	this.discountPolicy = discountPolicy;
    }
}

 

 

필드

 - OrderServiceImpl이 동작하기 위한 의존성 필드로 수정자주입에서는 'final' 키워드가 붙지 않는다.

@Autowired 애노테이션은 setter메서드에 의존성 주입이 필요하다는 것을 스프링에 알려 해당 타입의 빈을 찾아 주입한다.

Setter메서드 'setMemberRepository'를 통해 'MemberRepository'타입의 빈이 주입된다.

 

필드주입(Field Injection)

 - 변경 불가능한 의존관계를 설정할 수 없고 테스트하기 어렵다. 주로 테스트 코드나 간단한 Spring Boot애플리케이션에서 주로 사용된다.

@Component
public class OrderServiceImpl implements OrderService{

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

 

 

일반 메서드 주입(Method Injection)

 - 일반적인 메서드를 통해 의존관계를 주입받고 여러 필드를 한번에 주입받을 때 사용한다.

@Component
public class OrderServiceImpl implements OrderService{
	private MemberRepository memberRepository;
    private DiscountPolicy discountPolicy;
    
    @Autowired
    public void init(MemberRepository memberRepository, DiscountPolicy discountPolicy){
    	this.memberRespository = memberRepository;
        this.discountPolicy = discountPolicy;
    }
}

 

init 라는 일반 메서드를 정의하여 두개의 파라미터를 받아 내부 필드 값을 설정한다.

@Autowired 애노테이션에서 스프링컨테이너는 해당하는 메서드를 호출하여 파라미터에 해당하는 타입의 빈을 주입하게 된다.

 

--------------------------------------------------------------------------------------------------------------

 

옵션처리

 - 스프링에서 의존관계가 필수가 아닐때 또는 주입할 스프링 빈이 없어도 동작해야 할때가 있다. @Autowired 만 사용하면 required옵션의 기본값이 true로 되어 있어서 자동 주입대상이 없으면 오류가 발생한다.

 

1. @Autowired(required=false)

 - 자동으로 주입할 대상이 없다면 수정자 메서드 자체가 호출되지 않는다.

 - 이 방법은 해당 빈이 없어도 스프링 컨테이너가 오류를 발생시키지 않고 대신 null이 주입된다.

 

@Autowired(required = false)
public void setNoBean1(Member member) {
    System.out.println("setNoBean1 = " + member); 
}

호출되지 않는다.

setNoBean1 : 메서드는 Member 타입의 빈이 존재하지 않기 때문에 해당 메서드는 호출이 되지 않는다. 결과적으로 실행도 되지 않는다.

 

2. org.springframework.lang.Nullable

 - 자동 주입할 대상이 없으면 null이 입력된다.

 - @Autowired 의 required=false와 유사하지만 메서드 파라미터에 붙여서 사용한다.

@Autowired
public void setNoBean2(@Nullable Member member) { 
    System.out.println("setNoBean2 = " + member); 
}

null 호출

setNoBean2 : 메서드는 @Nullable 애노테이션이 있어 Member타입의 빈이 존재하지 않아도 메서드를 호출되지만 member 파라미터로 null이 전달되어 결과같은 null이된다.

출력결과 setNotBean2 = null

 

3. Optional<>

 - 자동 주입할 대상이 없으면 Optional.empty가 입력된다.

@Autowired(required = false)
public void setNoBean3(Optional<Member> member) { 
    System.out.println("setNoBean3 = " + member); 
}

Optional.empty호출

setNotBean3 : 메서드는 Optional<Member>를 사용했지만 @Autowired(required=false)와 함께 사용되어 해당하는 빈이 없으면 메서드 자체가 호출되지 않는다. 

만약 결과를 호출하고 싶다면 @Autowired(required=false)를 제거하고 Optional<Member>만 사용하면 Optional.empty라는 결과가 출력될 것이다.

출력결과 : setNotBean3 = Optional.null

728x90
반응형
LIST

'JAVA > Spring' 카테고리의 다른 글

Spring 컴포넌트스캔 (12)  (0) 2023.08.11
Spring Singleton, SingletionContainer (11)  (0) 2023.08.05
Spring BeenFactory와 ApplicationContext(10)  (0) 2023.08.04
Spring Been 조회 - 상속관계(9)  (0) 2023.07.16
Spring springBeen조회(8)  (0) 2023.07.16