[Spring] AppConfig

suhjaesuk·2022년 11월 9일
0

Spring

목록 보기
1/3
post-thumbnail

1) AppConfig, 관심사 분리

AppConfig는 애플리케이션의 전체 방식을 구성(config)하기 위해, 구현 객체를 생성하고 연결하는 책임을 가지는 별도의 설정 클래스입니다. 아래에서는 회원서비스를 담당하고 있는 클래스 MemberServiceImpl 을 예시로 들겠습니다.

1-1) AppConfig 생성 전 MemberServiceImpl

public class MemberServiceImpl implements MemberService {
    private final MemberRepository memberRepository = new MemoryMemberRepository();
    
public void join(Member member) { 
        memberRepository.save(member); 
    }
    public Member findMember(Long memberId) { 
        return memberRepository.findById(memberId);
	}
}
  • 위 코드는 인터페이스와 구체 클래스가 함께 의존한다. (DIP 위반)
  • 인터페이스에만 의존하도록 의존관계를 변경 후, AppConfig를 만들어 생성자 주입을 해주어야 한다 (구현객체를 대신 생성하고 주입)
  • 관심사를 분리하여 한개의 객체는 한개의 책임을 갖게 하자.

1-2) AppConfig 생성

public class AppConfig {

    public MemberService memberService() {
        return new MemberServiceImpl(new MemoryMemberRepository()); //생성자 주입
    }
}
  • 애플리케이션의 실제 동작에 필요한 구현 객체를 생성한다.
    • MemberServiceImpl
    • MemoryMemberRepository
  • 생성한 객체 인스턴스의 참조를 생성자를 통해서 주입한다. (생성자 주입)
    • MemberServiceImplMemoryMemberRepository

1-3) MemberServiceImpl 수정

public class MemberServiceImpl implements MemberService {
    private final MemberRepository memberRepository; //어떤객체가 주입될지 알수없다
                                                    //1개의 책임. 실행에만 집중
    public MemberServiceImpl(MemberRepository memberRepository) { //생성자 생성
        this.memberRepository = memberRepository; 
    } 
    public void join(Member member) { 
        memberRepository.save(member); 
    }
    public Member findMember(Long memberId) { 
        return memberRepository.findById(memberId); 
    }
}
  • MemberServiceImpl은 이로인해 DIP를 지킬 수 있다. (인터페이스에만 의존)
  • MemberServiceImpl 의 생성자를 통해 어떤 구현 객체를 주입할지는 AppConfig 에서 결정된다.
  • MemberServiceImpl은 의존관계에 대한 고민은 외부에 맡기고 실행에만 집중 할 수 있다.

2) 클래스 다이어그램

  • 객체의 생성과 연결은 AppConfig 가 담당한다.
  • MemberServiceImplMemberRepository 인 추상에만 의존하면 된다. (DIP)
  • 객체를 생성하고 연결하는 역할과 실행하는 역할이 명확히 분리된다. (관심사 분리)

3) 회원 객체 인스턴스 다이어그램

  • AppConfigmemoryMemberRepository 객체를 생성하고 그 참조값을 memberServiceImpl 객체를 생성하면서 생성자로 전달한다.
  • 다이어그램을 보면 memberServiceImpl 에서 의존관계를 외부에서 주입해주는 것 같다고 해서 이를 DI(Dependency Injection) 우리말로 의존관계 주입 또는 의존성 주입이라 한다.

4) AppConfig 리팩토링

현재 AppConfig는 역할에 따른 구현이 잘 안보입니다. 아래와 같이 리팩토링을 진행합니다.

@Configuration
public class AppConfig {
	@Bean
    public MemberService memberService() { 
        return new MemberServiceImpl(memberRepository()); //역할
    }
    @Bean
	public MemberRepository memberRepository() { 
        return new MemoryMemberRepository(); //구현
    }
}
  • 역할과 구현 클래스가 한눈에 들어온다. 애플리케이션 전체 구성이 어떻게 되어있는지 빠르게 파악할 수 있다.

5) 어플리케이션

  • 회원 서비스 어플리케이션인 MemberAppAppConfig 객체 생성
  • 정상적으로 실행됨
public class MemberApp {
    public static void main(String[] args) {
    	ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        MemberService memberService = applicationContext.getBean("memberService", MemberService.class);
        Member member = new Member(1L, "memberA", Grade.VIP);
        memberService.join(member);

        Member findMember = memberService.findMember(1L);
        System.out.println("new Member = "+ member.getName());
        System.out.println("find Member = "+ findMember.getName());
    }
}
// 출력 new Member = memberA
//	    find Member = memberA

📌 Ref. 김영한님의 스프링 핵심 원리

profile
wanna be BE-Developer

0개의 댓글