하나씩 차근차근

앞에서 스프링 컨테이너가 @Autowired 애노테이션을 찾아서 스프링 빈을 자동으로 주입했습니다.

이렇게 의존관계를 주입하는것은 아래와 같이 다양한 방법이 있습니다.

  • 생성자 주입
  • 수정자 주입
  • 필드 주입
  • 일반 메서드 주입
  • 롬복을 사용한 주입

 

생성자 주입

생성자 주입 방법은 지금까지 사용한 방법으로 생성자 호출시점에 딱 1번 호출됩니다.

package hello.core.order;
...
@Component
public class OrderServiceImpl implements OrderService{

	private final MemberRepository memberRepository;
	
	private final DiscountPolicy discountPolicy;

	@Autowired
	public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
		// TODO Auto-generated constructor stub
		this.memberRepository = memberRepository;
		this.discountPolicy = discountPolicy;
	}
	...
}

OrderServiceImpl (MemberRepository memberRepository, DiscountPolicy discountPolicy) 통해 주입합니다.

 

수정자 주입

필드의 값을 변경하는 setter 메서드를 통해서 의존관계를 주입하는 방법입니다.

package hello.core.order;
...
@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(DiscountPolicy discountPolicy) {
		this.discountPolicy = discountPolicy;
	}
	...
}

 

필드 주입

필드에 바로 주입하는 방법으로 간단하지만 외부에서 변경이 불가능하는 단점이 있습니다.

package hello.core.order;
...
@Component
public class OrderServiceImpl implements OrderService{

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

 

일반 메서드 주입

일반 메서드를 만들어서 주입을 받을 수 있으며, 한번에 여러 필드를 주입할 수 있습니다.

package hello.core.order;
...
@Component
public class OrderServiceImpl implements OrderService{

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

 

롬복을 사용한 주입

롬복을 사용한 방법은 롬복 라이브러리가 제공하는 @RequiredArgsConstructor 기능을 사용한 방식입니다.

package hello.core.order;
...
@Component
@RequiredArgsConstructor
public class OrderServiceImpl implements OrderService{

	private final MemberRepository memberRepository;
	
	private final DiscountPolicy discountPolicy;
	...
}
@RequiredArgsConstructor 는 final 이 붙은 필드의 생성자를 자동으로 만들어줌

 

옵션

  • @Autowired(required = false)
  • @Nullable
  • Optional<>

@Autowired 는 주입할 대상이 없으면 오류가 발생합니다.

주입할 대상이 없어도 동작하게 하려면 @Autowired(required = false ) 로 옵션을 줘야 합니다.

package hello.core.order;
...
@Component
@RequiredArgsConstructor
public class OrderServiceImpl implements OrderService{

	private final MemberRepository memberRepository;
	
	private final DiscountPolicy discountPolicy;
	
	@Autowired(required =  false)
	public void setNoBean1(Member member) {
		System.out.println("setNoBean1 = " + member);
	}
    ...
}
@Autowired 의 기본 옵션은 (required = true)

이 외에도 @Nullable 과 Optional<> 을 사용한 방법이 있습니다.

@Nullable 은 주입할 대상이 없으면 null 이 입력되며, Optionanl<> 은 Optional.empty 가 입력됩니다.

package hello.core.order;
...
@Component
@RequiredArgsConstructor
public class OrderServiceImpl implements OrderService{

	private final MemberRepository memberRepository;
	
	private final DiscountPolicy discountPolicy;

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

 

profile

하나씩 차근차근

@jeehwan_lee

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!