[Spring] 의존성 주입 - DI (Dependency Injection)

yjkim97·2023년 7월 10일
0

Spring & Spring boot

목록 보기
3/6
post-thumbnail

DI란?

  • DI : Dependency injection(의존성 주입)
  • IoC를 구현하기 위해 사용하는 방법이 DI이다.
  • 위치에 구애받지 않고 IoC 기법을 통해 Spring이 관리하는 객체(Bean)에 대한 종속성을 정의하는 것이다.

1. DI의 방식

DI에는 생성자 기반setter 기반 두가지 방식이 있다.

주로 필수 종속성에 대해서는 생성자 기반을 사용하고 선택적 종속성에 대해서는 setter 기반을 사용하는 것이 좋다.

1) 생성자 기반

  • 클래스의 생성자 인수를 통해 종속성을 주입한다.
  • 클래스가 인스턴스화될 때 이루어진다.
public class SimpleMovieLister {

	private final MovieFinder movieFinder;

	public SimpleMovieLister(MovieFinder movieFinder) {
		this.movieFinder = movieFinder;
	}
}

2) setter 기반

  • 클래스가 인스턴스화한 후 Bean에서 setter 메서드를 호출하여 주입하는 방식이다.
public class SimpleMovieLister {

	private MovieFinder movieFinder;
    private int i;

	public void setMovieFinder(MovieFinder movieFinder) {
		this.movieFinder = movieFinder;
	}
    
    public void setIntegerProperty(int i)
    {
    	this.i = i;
    }
}

3) 필드 기반

  • @Autowired와 컴포넌트 스캔(@Compoment, @Controller, @Service 등) 어노테이션 사용
@Service
public class SimpleMovieLister {

	@Autowired
	private MovieFinder movieFinder;
}

2. Spring의 DI

Spring에는 Bean을 생성하고 관리해주는 ApplicationContext, BeanDefinition이 존재한다.
ApplicationContext는 관리되는 Bean에 대해 생성자 기반 및 setter 기반 DI를 지원한다.

하지만 Spring/Java 개발자는
@Component, @Controller 등의 어노테이션을 통해 Bean 생성을 Spring에게 맡기고 ▶️ IoC
@Autowried, @RequiredArgsConstructor 등의 어노테이션을 통해 쉽게 주입하여 사용하거나, 생성자 또는 setter 메서드를 통해 종속성을 주입하여 Bean을 사용할 수 있다. ▶️ DI

💡 Spring의 DI 프로세스

  • ApplicationContext 모든 Bean을 설명하는 구성 메타데이터로 생성되고 초기화된다.
    구성 메타데이터는 XML, Java 코드 또는 Annotation 등으로 설정 할 수 있다.
  • 각 Bean에 대한 종속성은 속성, 생성자 인수 또는 setter 메서드를 통해 이루어진다.
  • 종속되는 Bean은 다른 Bean에 대한 참조이거나 실제 값이다.
  • 값인 각 속성 또는 생성자 인수는 지정된 형식에서 해당 속성 또는 생성자 인수의 실제 유형으로 변환된다. int기본적으로 Spring은 문자열 형식으로 제공된 값을 , long, String, boolean등과 같은 모든 내장 유형으로 변환할 수 있다.

Spring 컨테이너는 컨테이너가 생성될 때 각 Bean의 구성을 검증하고 종속성(DI) 설정은 Bean이 실제 생성될 때 이루어진다.
이때 DI로 인해 주입되는 또다른 Bean은 이미 인스턴스화 된 객체로 이를 싱글톤 패턴이라고 한다.
생성자 기반 DI를 사용하는 경우 개발자는 순환 참조 발생을 주의해야한다.

💡 순환 참조 (순환 종속성)

  • 주로 생성자 주입을 사용하는 경우 해결할 수 없는 순환 참조가 발생될 수 있다.

  • 예를 들면 아래와 같이 A 생성자에서 B를 주입하려하고 B 생성자에서 A를 주입하려고 할 때, Spring IoC 컨테이너는 런타임에 인스턴스 순환 참조를 감지하고 BeanCurrentlyInCreationException을 발생시킨다.

     public class A {
         private final B b;
         public A (B b)
         {
             this.b = b;
         }
     }
    
     public class B {
         private final A a;
         public B (A a)
         {
             this.a = a;
         }
     }

    이 경우 해결책은 setter 메소드를 사용하도록 수정하는 것이다.

싱글톤 패턴
https://tecoble.techcourse.co.kr/post/2020-11-07-singleton/

3. 장점

  1. 코드가 깔끔해진다.
  2. Bean이 독립적이다.

Reference

profile
어제는 🐸두꺼비 오늘은 😄YJ

0개의 댓글