개발 무지렁이

[Spring] 의존성 주입(DI)에 의한 의존관계 조립 본문

Backend/스프링

[Spring] 의존성 주입(DI)에 의한 의존관계 조립

Gaejirang-e 2023. 9. 9. 20:28

𐂂 의존관계
하나의 클래스 내에서 다른 객체를 포함하고 있을 때,
'이 클래스가 해당 객체에 의존한다'라고 표현할 수 있다.

𐁍 Dependency Injection(의존성 주입, DI) 이란
의존관계를 만들어 주기위해, 외부에서 객체를 생성해서 클래스 내에 주입하는 것을 의미한다.
즉, 외부(🪺Spring Container)에서 싱글톤으로(하나만 등록해서 공유) 객체를 생성해서 주입해주는 것을 말한다.

WHY 싱글톤으로 객체를 생성하는 이유
Controller, Service, Repository에 있는 메서드를 호출하는 것이 목적이기 때문에, 굳이 여러개 만들 필요가 없다.
하나만 생성해서 공용으로 쓰면된다.
🪺Spring Container등록하면 딱 하나만 등록된다.

⚠️ 같은 Spring Bean이면 모두 같은 인스턴스다.

🥚 Bean : Spring Container가 관리하는 객체

𖠃 Spring이 Bean을 등록하는 2가지 방법
(1) @Component 어노테이션이 있으면 스프링 빈(Bean)으로 자동 등록된다.
: @Controller, @Service, @Repository 어노테이션 안에 @Component가 포함되어 있다.

따라서, 🌱Spring이 올라올 때, 컴포넌트 스캔(Component-scan)을 하고,
@Component 관련 어노테이션이 붙은 클래스를 보며,
🪺Spring Container가 관리하는 객체인지 아닌지 여부를 알 수 있다.
🥚Spring Bean에 등록된 객체에 한에서서 관련 필드 or 생성자 or 메서드에 @Autowired 어노테이션을 붙으면
🪺Spring Container에 있는 🥚Spring Bean에 등록되어 있는 객체를 가지고 온다.
이러한 방식으로 의존관계를 주입할 수 있다.

🦉 컴포넌트 스캔(Component-scan)은 어디서부터 수행할까?

: 진입점 함수(main)이 있는 [클래스명]Application.java에는 항상 @SpringBootApplication 어노테이션이 붙는다.
@SpringBootApplication@ComponenetScan 어노테이션을 포함한다.
이 클래스가 들어있는 패키지를 포함한 하위 자바파일에 있는 어노테이션만 🥚Spring Bean 등록한다.

𖠃 자바코드로 직접 스프링 빈 등록하기

📜 SpringConfig.java

  // Spring이 올라올 때, @Configuration 어노테이션을 읽는다
  @Configuration
  public class SpringConfig {
      @Bean
      public MemberService memberService() {
          return new MemberService(memberRepository());
      }

      @Bean
      public MemberRepository memberRepository() {
          return new MemoryMemberRepository();
      }
  }
의존성 주입(DI)에는 필드주입, 생성자 주입, Setter주입이 있다.
Setter주입은 권장되지 않는다. 왜냐하면, Controller -> Service -> Repository로 이어지는 의존관계는
처음 조립할 때 한번만 바꿔치기 하는거지, 한번 조립이 되면 바꿀일이 없다.
따라서 의존관계가 실행중에 동적으로 변하는 경우가 없으므로, 이를 조립 이후에도 바꿀 수 있는
Setter 주입은 권장되지 않는다. 처음 한번만 조립할 때, 상황에 맞게 바꿔치기 좋은 의존성 주입방식은 생성자 주입이다.

Controller를 통해 외부 요청을 받고,
Service를 통해 비즈니스 로직을 만들고,
Repository를 통해 데이터를 저장하는게 정형화된 패턴이다.
정형화된 패턴에는 컴포넌트 스캔을 사용하는게 편리하지만,
상황에 따라 구현클래스가 바뀌는 경우 다음과 같이 자바 설정파일을 통해 스프링 빈으로 등록한다.
Comments