인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

아진짜님의 프로필 이미지
아진짜

작성한 질문수

스프링 핵심 원리 - 기본편

[섹션4.관심사의 분리] - 생성자를 통한 참조 주입 질문입니다.

작성

·

21

0

package hallo.core;

import hallo.core.discount.FixDiscountPolicy;
import hallo.core.member.MemberRepository;
import hallo.core.member.MemberService;
import hallo.core.member.MemberServiceImpl;
import hallo.core.member.MemoryMemberRepository;
import hallo.core.order.OrderService;
import hallo.core.order.OrderServiceImpl;


public class AppConfig {

    //생성자 주입
    // -> MemberServiceImpl 은 추상에만 신경쓴다. 따라서
    // new MemoryMemberRepository() 객체가 AppConfig 외부에서 생성되어 들어간다
    //MemberServiceImpl 를 생성하면서 MemoryMemberRepository 를 쓸거야!
    //AppConfig는 생성자 객체인스턴의 참조(레퍼런스)를 생성자를 통해서 주입(연결 한다)
    public MemberService memberService() {
        return new MemberServiceImpl(new MemoryMemberRepository());
    }
    //------생성자를 통한 참조 주입(1) ----------------------------------------
    // MemberService() 메서드가 호출되면 new MemoryMemberRepository()가 실행되어
    //MemoryMemberRepository() 객체가 생성 된다. 이 객체의 참조값(메모리 주소)이
    //MemberServiceImpl의 생성자 매개변수로 전달된다
    public OrderService orderService() {
        return new OrderServiceImpl(
                new MemoryMemberRepository(),
                new FixDiscountPolicy());
    }


}

public class MemberServiceImpl implements MemberService {
    private MemberRepository memberRepository; // AppConfig 에서 관리
 //AppConfig 는 생성자 객체인스턴의 참조(레퍼런스)를 생성자를 통해서 주입(연결 한다)
    public MemberServiceImpl(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }
    //------생성자를 통한 참조 주입(2) ----------------------------------------
    //전달받은 참조값을 MemberServiceImpl 클래스의 필드인 memberRepository에 할당.
    //MemberServiceImpl 인스턴스의 memberRepository 필드는 AppConfig에서 생성된 MemoryMem   berRepository
    //객체의 참조값을 가지게 된다.
    //AppConfig에서 생성된 MemoryMemberRepository 객체의 참조값은 매개변수 memberRepository -> 필드 memberRepository  순서로
    //전달되어 최종적으로 클래스 필드에 저장된다.

} 생성자를 통한 참조 주입을 제가 정리해 보았습니다.
실제로 메모리에 할당 될 때 [AppConfig]
new MemoryMemberRepository() -----> 메모리 주소(예: x001) 
                                     ↑
[MemberServiceImpl]                  |
memberRepository -------------------|
이렇게 할당이 될 것이라고 생각하는데 제가 정리한 것과 흐름이 맞는지 궁금합니다.
그리고 MemoryMemberRepository()); 이 부분은 객체생성을 하면서 참조값을 만들지만 참조값을 받는 변수가 없는데 어떻게 참조값을 인식하는지 궁금합니다.
답변 주시면 감사하겠습니다.

답변 1

0

안녕하세요. 아진짜님, 공식 서포터즈 y2gcoder입니다.

제가 아진짜님의 질문을 제대로 이해했는지 모르겠습니다!

먼저 생성자를 통한 의존성 주입에 대해서는 잘 이해하신 것 같습니다!

질문과 더불어 전체적으로 정리하는 느낌으로 말씀드리고 싶습니다!

return new MemberServiceImpl(new MemoryMemberRepository());

위의 코드를 보시면 MemberServiceImpl() 인스턴스를 생성할 때 new MemoryMemberRepository() 를 통해 MemoryMemberRepository 의 생성자도 호출하여 MemoryMemberRepository 인스턴스를 생성 후 그 반환값(참조값이겠죠?)을 MemberServiceImpl 의 생성자에 넣어주고 있습니다. 그러면 MemberServiceImpl 의 생성자를 확인해보겠습니다.

public class MemberServiceImpl implements MemberService {
    private MemberRepository memberRepository;

    public MemberServiceImpl(MemberRepository memberRepository) {
        this.memberRepository = memberRepository
    }
}

보시면 아까 말씀드렸던 MemberServiceImpl 의 생성자가 있습니다. 생성자의 내부 구현을 보면 MemberRepository 타입의 객체를 받아 자신의 필드인 memberRepository 에 대입해주고 있는 것을 보실 수 있습니다. 저희는 아까 MemberServiceImpl의 생성자를 호출할 때 MemberRepository 인터페이스의 구현체인 MemoryMemberRepository 의 생성자를 호출해 해당 인스턴스를 받아서 (그 참조값을) 해당 생성자의 파라미터로 넣어주었습니다.

이 부분의 설명이 조금 어렵다고 생각이 드신다면 자바의 인터페이스, 구현체의 다형성을 공부해보시면 좀 더 쉽게 이해가 되실 거라 생각합니다 🙂

영한님의 실전 자바 시리즈 강의를 수강해보시는 것을 권해드리고 싶습니다 🙂

감사합니다.

아진짜님의 프로필 이미지
아진짜

작성한 질문수

질문하기