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

SeokHun·2021년 1월 9일
0

Spring

목록 보기
1/4

Core Technologies


Dependency Injection

의존성(Dependency) 이란?

  • 둘 이상의 객체가 협력하는 방법
  • 하나의 객체의 변화가 다른 객체에 영향을 미치는 것

하나의 객체가 변화할 때 다른 객체도 변화를 주어야 하기 때문에 이를 효과적으로 관리할 필요가 있다
= Dependency Injection

Container가 Bean을 생성할 때 객체 Instance에 설정된 속성을 통해서 다른 객체를 정의하는 프로세스이다

생성자 의존성 주입

자바 생성자에서 받는 여러 인수를 통해 Container가 의존성을 주입

// 예시
public class SimpleMovieLister {
    // SimpleMovieLister가 MovieFinder에게 의존하고 있을 때
    private MovieFinder movieFinder;

    // 생성자를 통해 Spring container가 MovieFinder 의존성을 주입
    public SimpleMovieLister(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }
}

Setter 의존성 주입

자바 클래스에서 Setter 함수를 통해 Container가 의존성을 주입

// 예시
public class SimpleMovieLister {
    // SimpleMovieLister가 MovieFinder에게 의존하고 있을 때
    private MovieFinder movieFinder;

    // Setter 함수를 통해 Spring container가 MovieFinder 의존성 주입
    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }
}

@Component

  • Bean의 의존성 주입을 위해 @Autowired를 사용할 때 해당 Annotation으로 만든 Bean을 사용할 수 있다.
  • 개발자가 직접 작성한 Class를 Spring Container에 Bean으로 등록하는 Annotation 이다.
  • @Bean으로 Spring Container에 Bean을 등록할 수 있지만, 개발자가 작성한 Method를 통해 반환되는 객체를 Bean으로 활용할 수 있는 제한이 있다.
// 예시 SomethingRepositoryImplement
package ~.Something.domain

import org.springframework.stereotype.Component;

@Component
public class SomethingRepositoryImpl implements SomethingRepository{
	~
	@Override
	~
}

[Spring] @Autowired

@Autowired

  • 생성자나 Setter 함수를 통해 의존성 주입을 하려고 할 때, 해당 빈을 찾아서 주입해주는 Annotation

  • Option
    @Autowired(required = true) : 의존성 주입에 필요한 객체가 무조건 Bean으로 등록되어야 함
    @Autowired(required = false) : Setter의 파라미터가 주입되어야 하는 경우 Bean 등록이 안되어 있어도 오류가 나지 않고 인스턴스를 만든다.
    * Default 값은 true 이다.

// 예시 SomethingRepository
package ~.Something.domain

public interface SomethingRepository { ~ }
// 예시 SomethingService
package ~.Something.application

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class SomethingService{
	@Autowired
	SomethingRepository somethingRepository;
	~
}
  • 같은 타입의 Bean이 여러 개인 경우

예시로 Service라는 객체가 있고 그 객체에서 Repository를 사용하기 위해 의존성 주입을 받는다고 가정

@Repository
public class SomethingRepositoryImpl1 implements SomethingRepository{ ~ }
@Repository
public class SomethingRepositoryImpl2 implements SomethingRepository{ ~ }

이 경우 @Autowired를 사용해서 의존성 주입을 받으려고 하면 에러가 난다.

* 해결방법

  • @Primary
    동일한 타입의 빈들 중 하나에 @Primary Annotation을 붙여준다.
    그럼 그 빈이 우선권을 가지게 되어, 프로그램 실행 시, 해당 Bean으로 의존성주입을 받아온다.

  • @Qualifier
    빈의 id값으로 어떤 bean을 사용할지 정해준다.
    이 경우는 의존성 주입 해주는 쪽, 즉 @Autowired를 사용하고 있는 곳에 해준다.
    빈의 id는 의존성 주입을 받아와야 하는 타입의 클래스 명의 맨 앞 글자를 소문자로 바꾼 것이다.

  • 동일한 타입의 모든 Bean을 리스트로 받아오기
    List를 사용하여 같은 타입의 bean들을 모두 리스트에 담아주고 사용하는 것이다.
    (@PostConstruct 라는 Annotation을 이용하여 List를 출력할 수 있다.)

0개의 댓글