
@Component
public class OrderServiceImpl implements OrderService{
private MemberRepository memberRepository;
private DiscountPolicy discountPolicy;
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
}
✅ 생성자를 통해 주입 하는 방법
- 생성자 호출 시점에 딱 1번만 호출되는 것이 보장됨
불변,필수의존관계에 사용
✨ 생성자가 딱 1개만 있을 땐 @Autowired를 생략해도 된다.
@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;
}
}
✅ 수정자를 통해 주입 하는 방법
- 자바빈 프로퍼티 규약의 수정자 메서드 방식을 사용하는 방식
선택,변경의 가능성이 있는 의존관계에 사용
✨ @Autowired 는 주입할 대상이 없으면 오류가 발생한다. 주입할 대상이 없어도 동작하게 하려면 @Autowired(required = false)로 지정한다.
@Component
public class OrderServiceImpl implements OrderService{
@Autowired
private MemberRepository memberRepository;
@Autowired
private DiscountPolicy discountPolicy;
}
✅ 필드를 통해 주입 하는 방법
- 외부에서 변경이 불가능해서 테스트하기 힘들다
- DI 프레임워크가 없으면 아무것도 할 수 없다
@Configuration과 같은 곳에서만 특별한 용도로 사용
✨ 사용하지 말자!
@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;
}
}
✅ 일반 메서드를 통해 주입 하는 방법
- 한 번에 여러 필드를 주입받을 수 있다.
✨ @Autowired 는 스프링 컨테이너가 관리하는 스프링 빈이어야 동작한다. 예를들어, 스프링 빈으로 등록하지 않았던 Member와 같은 클래스에서는 @Autowired가 동작하지 않는다.
@Autowired(required=false) : 자동 주입할 대상이 없으면 메서드 호출 X@Nullable : 자동 주입할 대상이 없으면 null 입력Optional<> : 자동 주입할 대상이 없으면 Optional.empty가 입력된다.package hello.core;
import hello.core.member.Member;
import jakarta.annotation.Nullable;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import java.util.Optional;
public class OptionTest {
@Test
void OptionTest(){
ApplicationContext ac = new AnnotationConfigApplicationContext(TestBean.class);
}
static class TestBean{
@Autowired(required = false)
public void setNoBean1(Member member){
System.out.println("noBean1 = " + member);
}
@Autowired
public void setNoBean2(@Nullable Member noBean2){
System.out.println("noBean2 = " + noBean2);
}
@Autowired(required = false)
public void setNoBean3(Optional<Member> member){
System.out.println("noBean3 = " + member);
}
}
}

method setNoBean1(hello.core.member.Member) is already defined in class hello.core.OptionTest.TestBean

이미 메서드가 정의되어 있다는 에러가 발생했다.. 이상하다..
package hello.core;
import hello.core.member.Member;
import jakarta.annotation.Nullable;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import java.util.Optional;
public class OptionTest {
@Test
void OptionTest(){
ApplicationContext ac = new AnnotationConfigApplicationContext(TestBean.class);
}
static class TestBean{
@Autowired(required = false)
public void setNoBean1(Member member){
System.out.println("noBean1 = " + member);
}
@Autowired
public void setNoBean1(@Nullable Member noBean2){
System.out.println("noBean2 = " + noBean2);
}
@Autowired(required = false)
public void setNoBean3(Optional<Member> member){
System.out.println("noBean3 = " + member);
}
}
}