스프링 빈과 의존관계

김민석·2021년 2월 4일
0

스프링 빈(Bean)

스프링 컨테이너가 관리하는 자바 객체를 빈(Bean)이라 한다.
자바에서 객체를 생성할 때 주로 new를 통해 생성하는데, 이 객체를 의미하는 것이 아니라 컨테이너에서 스스로 생성하고 관리하는 객체를 의미한다.
컨테이너에서의 관리를 통해 객체를 여러번 생성할 필요가 없고, 공용으로 사용할 수 있다.

스프링 빈 등록하기

스프링 빈을 컨테이너에 등록하는 방법으로는 두 가지 방법이 있다.

  1. 컴포넌트 스캔 원리
  2. 자바 코드를 통해 직접 등록

1. 컴포넌트 스캔 원리

@Component 어노테이션이 있으면 스프링 빈으로 자동 등록된다.
주로 정형화된 컨트롤러 - 서비스 - 리포지토리 같은 코드는 컴포넌트 스캔 원리를 활용한다.
정형화된 코드는 @Component 대신 @Controller, @Service, @Repository를 사용할 수 있는데, 이 세 가지 어노테이션들이 @Component라는 어노테이션을 포함하기 때문이다.

회원 컨트롤러 생성

그림과 같이 controller 패키지에 클래스를 하나 생성해 준다. 그리고 @Controller 어노테이션을 넣어준다.
그리고 서비스객체를 연결해 주기 위해 생성자에 @Autowired 어노테이션을 넣어준다. 이 과정은 의존관계를 넣어주기 위한 과정인데 이 부분은 나중에 설명하겠다.
서비스객체와 연결을 해 줘야 하는데, 서비스 코드는 순수한 자바 코드이기 때문에 마찬가지로 컨테이너에 등록을 해 줘야 한다.

회원 서비스 스프링 빈 등록

@Service 어노테이션을 통해 스프링 빈으로 등록을 해 준다.
마찬가지로 서비스와 리포지토리를 연결해 주기 위해 @Autowired 어노테이션을 넣어준다.

회원 리포지토리 스프링 빈 등록

@Repository 어노테이션을 통해 스프링 빈으로 등록을 해 준다.

2. 자바 코드를 통한 직접 등록

앞선 방법이 정형화된 코드에서 사용하는 방법이라면 자바 코드를 통해 직접 등록하는 방법은 주로 정형화 되지 않거나, 상황에 따라 구현 클래스를 변경해야 하는 경우에 사용한다.
현재 사용하는 예제에서 데이터베이스를 아직 정하지 못한 상황으로 가정하였으므로 향후 메모리 리포지토리를 다른 리포지토리로 변경할 예정이므로 자바 코드를 통한 직접 등록 방식을 사용할 것이다.

configuration 생성
컨트롤러의 경우 스프링이 직접 관리하기 때문에 컨트롤러의 어노테이션 부분은 그대로 유지를 한 채로 서비스의 어노테이션(Service, Autowired)와 리포지토리의 어노테이션(Repository)를 제거해 준다.
클래스를 하나 생성하고 그 클래스에 @Configuration 어노테이션을 붙인다. 그리고 스프링 빈으로 등록할 객체들을 @Bean 어노테이션을 통해 직접 등록해 준다.

추가적으로 XML을 통해 등록을 하는 방법도 있지만 최근에는 잘 사용하지 않는다고 한다.


위의 과정들을 거쳐 그림과 같이 컨테이너에 컨트롤러, 서비스, 리포지토리가 스프링 빈으로 등록 되었다. 스프링 빈을 등록할 때 기본으로 하나만 등록하여 공유한다. 따라서 같은 스프링 빈이면 같은 인스턴스인 셈이다.

의존성 주입(DI, Dependency Injection)

의존성 주입이란 객체간의 의존성을 자신이 아닌 외부에서 주입해 주는 것이다.
만약 코드 만으로 의존성을 부여해 준다면 기능을 변경할 경우 의존 관계가 있는 코드들을 수정해 줘야 하는 상황이 올 수 있다. 이런 문제들을 해결하기 위해 외부에서 의존 관계를 주입하는 것이다.

스프링에서는 @Autowired 어노테이션을 이용하여 연관된 객체를 컨테이너에서 찾아서 의존성을 넣어준다. 추가적으로 @Autowired를 통한 의존성 주입은 스프링이 관리하는 객체에서만 동작하며 스프링 빈으로 등록하지 않고 직접 생성한 객체에서는 동작하지 않는다.

스프링에서는 세 가지 방법으로 의존성을 주입한다.

1. 생성자 주입
생성자 주입은 예제에서 활용한 방식과 같이 생성자를 통해 의존성을 주입하는 것이다.
의존관계가 실행중에 동적으로 변하는 경우는 거의 없으므로 생성자 주입이 자주 사용된다.

2. 필드 주입

그림과 같이 필드에 직접 의존성을 넣어주는 것이다. 코드량이 줄어드는 장점이 있지만 클래스 의존관계가 명확하지 않은점과 강한 결합으로 인한 외부에서의 사용이 어려워 진다는 점 때문에 자주 사용하지 않는다.

3. setter 주입

그림과 같이 setter를 통해 의존성을 넣어주는 것이다. public하게 노출되어 사용되므로 안전하지 않다는 점이 있지만 선택적이거나 변경 가능성이 있는 경우 사용된다.

출처 : 인프런 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8/lecture/49587?tab=curriculum&speed=1

profile
김민석의 학습 정리 블로그

0개의 댓글