스프링/1. 스프링 핵심 원리

33강. 의존자 주입 방법들

sdafdq 2023. 7. 22. 00:26

생성자 주입

수정자 주입(setter 활용)

필드 주입

일반 메서드 주입

 

 

@Component
public class MemoryMemberRepository implements MemberRepository{
    @Autowired
    private static Map<Long, Member> store = new HashMap<>();   //Map, id랑 Member 객체 간이적으로 메모리에 저장
    @Override
    public void save(Member member) {
        store.put(member.getId(), member);
    }

    @Override
    public Member findById(Long memberId) {
        return store.get(memberId);
    }
}

이렇게 생성자 주입해줌.

@Autowired

 

자동으로, 한번만 생성해주는게 보장됨.

그래서 보통 불변, 필수인 의존관계에 씀.

 

 

딱 생성자를 통해서만 의존관계가 주입되고, 어느 누구도 필드를 수정할 수 없다.

그래서 이런 거에는 setter 안놔둠. 

 

 

생성자가 하나일 때는 @Autowired 안해도 된다고 하던데 그래도 명시적으로 해두는 게 좋지 않나?

 

 

 

 

 

@Component
public class OrderServiceImpl implements OrderService{
    private MemberRepository memberRepository;
    private DiscountPolicy discountPolicy;

    public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
        this.memberRepository = memberRepository;
        this.discountPolicy = discountPolicy;
    }
    @Override
    public Order createOrder(Long memberId, String itemName, int itemPrice) {
        Member member = memberRepository.findById(memberId);
        int discountPrice = discountPolicy.discount(member, itemPrice);

        return new Order(memberId, itemName, itemPrice, discountPrice);
    }


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

}

이런 식으로 setter에 @Autowired를 붙여 생성자 주입 가능.

setMem 이 이름 규칙때문에 알아서 찾는 듯.

 

 

그리고 setter 의존관계 주입하더라도, 결국 생성하려면 생성자를 호출해야 하기 때문에 @Autowired 없어도 생성자 알아서 호출 하는 듯.. 그 후에 setter 하는거임.

 

 

@Autowired는 주입할 대상이 없으면 오류가 발생하는데, 주입할 대상이 없어도 동작하도록 하려면 @Autowired(required = flase) 쓰면 됨

 

 

선택, 변경 가능성이 있을 때 이렇게 씀.

 

 

 

필드 주입

@Component
public class OrderServiceImpl implements OrderService{
    @Autowired private MemberRepository memberRepository;
    @Autowired private DiscountPolicy discountPolicy;

    public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
        this.memberRepository = memberRepository;
        this.discountPolicy = discountPolicy;
    }
    @Override
    public Order createOrder(Long memberId, String itemName, int itemPrice) {
        Member member = memberRepository.findById(memberId);
        int discountPrice = discountPolicy.discount(member, itemPrice);

        return new Order(memberId, itemName, itemPrice, discountPrice);
    }
}

private 인데도 넣어줌.

이건 안씀.

 

 

외부에서 변경이 불가능. 그래서 순수자바코드로 Test하기 어려움. 무조건 스프링 컨테이너 띄우고 거기서 bean을 가져와야 됨.

DI 프레임워크가 없으면 아무것도 못함.

 

 

 

일반 메서드 주입

@Autowired는 아무 메서드나 사용 가능.

 

@Component
public class OrderServiceImpl implements OrderService{
    private MemberRepository memberRepository;
    private DiscountPolicy discountPolicy;

    public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
        this.memberRepository = memberRepository;
        this.discountPolicy = discountPolicy;
    }
    @Override
    public Order createOrder(Long memberId, String itemName, int itemPrice) {
        Member member = memberRepository.findById(memberId);
        int discountPrice = discountPolicy.discount(member, itemPrice);

        return new Order(memberId, itemName, itemPrice, discountPrice);
    }


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


}

한번에 여러 필드 주입가능

그러나 잘 쓰지 않음.. 굳이.. 생성자로 하면 되는데..

 

 

'스프링 > 1. 스프링 핵심 원리' 카테고리의 다른 글

35강. 생성자 주입을 사용하라.  (0) 2023.07.22
34강. 의존관계 주입 옵션  (0) 2023.07.22
32강. 충돌, 중복등록  (0) 2023.07.21
31강. 필터  (0) 2023.07.21
29강. 컴포넌트 스캔  (0) 2023.07.20