Heestory

02~03.스프링)핵심 원리 이해 본문

개발(~국비)/Spring

02~03.스프링)핵심 원리 이해

까만밀가루 2022. 10. 22. 21:25

순수한 자바 코드에 테스트 하는 것은 효율성이 떨어진다

EX. main 메소드에 System.out.println() 와 같은 ..

→ Junit 을 이용하자

 

Junit : given , when, then 형태로 진행한다

    @Test
    void join(){
        //given
        Member member = new Member(1L,"memberA",Grade.VIP);

        //when
        memberService.join(member);
        Member findMember = memberService.findMember(1L);

        //then
        Assertions.assertThat(member).isEqualTo(findMember);
        
        //결과적으로 join 후 find를 했다면 넣고 찾는게 제대로 되고 있다는 뜻
    }

 

역할 생성 후 구현체 만들기

DIP 원리에 의해 추상(인터페이스)에만 의존해야한다. → 애플리케이션의 전체 동작 방식을 구성(Config)하기 위해, 구현 객체를 생성하고, 연결하는 책임을 가지는 별도의 설정 클래스가 나타암(관심사 분리, 마치 공연 기획자)

AppConfig 등장 : 객체의 생성과 연결 담당

 

@Configuration
public class AppConfig {

    @Bean
    public MemberService memberService(){
        return new MemberServiceImpl(memberRepository());
    }

    @Bean
    public MemberRepository memberRepository() {
        return new MemoryMemberRepository();
    }
}

@Configuration : AppConfig에 설정을 구성한다

@Bean : 각 메서드에 붙이면 스프링 컨테이너에 스프링 빈으로 등록

→ @Bean에 붙은 메서드 명을 스프링 빈의 이름으로 사용

스프링 컨테이너를 통해서 필요한 스프링 빈(객체)를 찾아야 한다 ▶ applicationContext.getBean() 메서드 이용 

 

- 실제 동작에 필요한 구현 객체를 생성한다.

  • MemberServiceImpl 
  • MemoryMemberRepository

- 생성한 객체 인스턴스의 참조(레퍼런스)를 생성자를 통해서 주입(연결)해준다.

   MemberServiceImpl ▶ MemoryMemberRepository

 

public class MemberServiceImpl implements MemberService{

    private final MemberRepository memberRepository;

    // 생성자를 통해서 memberRepository에 뭐가 들어갈지를 정함
    public MemberServiceImpl(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }

오직 MemberRepository 인터페이스만 의존 → DIP 완성

- MemberServiceImpl 입장

  • 생성자를 통해 어떤 구현 객체가 들어올지(주입될지) 모른다
  • 생성자를 통해서 어떤 구현 객체를 주입할지는 오직 외부(AppConfig)에서만 결정
  • 의존관계에 대한 고민은 외부에 맡기고 실행에만 집증(구현에만 집중)

▶ 클라이언트인 memberServiceImpl 입장에선 외부에서 의존관계를 주입하는 거 같다고 하여

DI(Dependency Injection), 의존관계 주입 또는 의존성 주입 

-정적인 클래스 의존관계

: 애플리케이션을 실행하지 않아도 분석할 수 있다

클래스가 사용하는 import 코드만 보고 판단 가능, 단 실제 어떤 객체가 주입될지는 모름

-동적인 객체 인스턴스 의존 관계

: 애플리케이션 실행 시점에 실제 생성된 객체 인스턴스의 참조가 연결된 의존 관계

실행시점(런타임)에 외부에서 실제 구현 객체를 생성하고 클라이언트에 전달해서 클라이언트와 서버의 실제 의존관계가 연결되는 것

의존관계 주입을 사용하면 클라이언트 코드를 변경하지 않고, 클라이언트가 호출하는 대상의 타입 인스턴스를 변경할 수 있다.

→ 의존관계 주입을 사용하면 정적인 클래스 의존관계를 변경하지 않고, 동적인 객체 인스턴스 의존관계를 쉽게 변경가능

 

▶ 만약 구현 클래스에서 변경이 필요하다면 AppConfig만 변경하면 된다. 클라이언트 코드의 사용영역은 바꾸지 않아도 된다.

ex.할인 정책 변경 예시

 

 

loC(Inversion of Control) 제어의 역전

: AppConfig가 등장한 이후 구현 객체는 자신의 로직 실행하는 역할만 하며, 프로그램의 제어 흐름은 AppConfig가 가져간다. 이렇듯 프로그램 흐름 제어를 직접 하는 것이 아니라 외부에서 관리하는 것을 제어의 역전이라 한다.

 

※프레임워크 vs 라이브러리

- 프레임 워크가 내가 작성한 코드를 제어하고, 대신 실행하면 프레임워크(Junit)

- 라이브러리 : 내가 작성한 코드가 직접 제어의 흐름을 담당

 

loC 컨테이너, DI 컨테이너

- AppConfig처럼 객체를 생성하고 관리하면서 의존관계를 연결해주는 것

 

 

 

 


본 내용은 인프런 - 김영한 스프링 기본편 강의 내용 정리용으로 작성하였습니다

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8

 

스프링 핵심 원리 - 기본편 - 인프런 | 강의

스프링 입문자가 예제를 만들어가면서 스프링의 핵심 원리를 이해하고, 스프링 기본기를 확실히 다질 수 있습니다., - 강의 소개 | 인프런...

www.inflearn.com