본문 바로가기

SPRING

DI 의존성 주입 - Java / @Component, @Autowired

*의존성 주입

- 의존성: 하나의 객체가 다른 객체 없이는 제대로 된 역할을 할 수 없음을 의미, 다른 객체(클래스)를 꼭 필요로 하는 것

- 주입: 외부에서 자료를 넣어주는 것

- 예를 들어, 음악 프로그램에서 백댄서가 없어도 가수만이라도 있다면 어찌저찌 무대를 구성하는 것은 가능합니다.

  그런데 가수가 없고 백댄서만 있는 상황이라면 어떨까요? 이 경우는 무대 자체가 성립하지 않습니다.

  이 경우는 무대가 성립하기 위해 반드시 필요한 것이 가수이므로 무대는 가수에 의존한다 라고 표현할 수 있습니다.

  자바 내부로 따지면 A객체를 만드는데 A객체의 생성자가 B라는 객체를 파라미터값으로 요구한다면 A객체는 B객체 없이는

  만들 수 없게 되는 것입니다. 그래서 이 관계를 가리켜 의존 관계라고 부릅니다.

 

*bean-container

- 가상의 공간, 일종의 공장
- 완제품을 미리 생산해뒀다가 사용자가 제품을 주문하면 바로 조립해서 가져다 주는 공장

- 사용자는 이 공장에 미리 의존관계를 포함한 정보를 넘겨줄 수 있으며, 그렇게 넘어간 정보를 토대로

  bean-container 내부에 객체가 미리 생성

- 미리 만들어져있다는 특성으로 인해 사용자가 객체를 필요로 할 때는 직접 new 연산자를 이용해 객체를 생성하는 방식이 아니라

  bean-container에 미리 완성되어 있던 객체를 받아다 쓰는 형태로 코드가 진행

 

*의존성 주입 테스트 (java 방식)

console: 무대에서 가수가 노래를 합니다. / 가수가 노래를 합니다.

*의존성 주입 테스트 (Spring 방식)

1) bean container에 객체 등록하기 -> 객체 대기 상태

- root-context.xml 파일에 객체 등록 (보통 .xml 파일에 등록)

- <context:component-scan base-package = "패키지명" /> 태그 사용 

   -> 해당 패키지의 모든 클래스 파일이 스캔의 대상이 됨, 패키지명을 등록함으로써 스캔의 범위 지정

- 단지, 객체를 만들어 놓고 대기하고 있는 상태. 언제든 쓰라고 미리 만들어 놓고 호출을 기다리는 중. 둥둥 떠다니는중.

 

2) 컴포넌트 스캔 활용 및 객체 bean-container에 등록 -> 진짜 객체 생성

- 객체를 컴포넌트 스캔 처리하기 위해서는 두 가지 조건 필요

   1. 스캔 범위에 들 것  2. 클래스명 윗줄에 어노테이션을 사용할 것

   즉, 클래스명 윗줄에 어노테이션을 추가해야 빈 컨테이너가 어노테이션을 보고 '아~객체를 만드려고 하는구나'라고 알아차림

   이 클래스 쓰고 싶어. 그러면 클래스 위에 어노테이션 추가하면 둥둥 떠다니던 걸 고정시키는 과정 즉, 빈 그래프에 박제해버리기

   -> 빈 컨테이너 내부에 진짜 객체가 만들어져 있는 상태

- 객체에 따른 어노테이션 종류

   @Component -> 용도가 애매한 객체에 사용

   @Controller -> 컨트롤러에 사용
   @Service -> 서비스 객체에 사용

   @Repository -> DAO 객체에 사용

- 빈 그래프에서 컴포넌트 스캔을 통해 객체들이 등록된 것을 확인할 수 있음

- 컴포넌트 스캔이 정상적으로 완료되면, package explorer 상에서 class 파일 우상단에 S 라는 표식이 생김

 

3) 등록된 객체 간 주입 구현 -> 의존성 주입

- @Autowired 어노테이션을 이용해 자동 주입 구현 (자료형이 일치하는 객체에 한해서)
- 의존 객체 위(보통 멤버변수)에 @Autowired 어노테이션을 쓰면 bean-container가 자동으로 주입을 진행

- 주입을 알아서 진행해주기 때문에 최종 완성 객체 하나만 신경쓰면 됨

4) 메인 클래스에서 실제 객체 생성하기

- 실제 객체 생성을 위해서는 아래와 같이 GenericXmlApplicationContext 클래스의 객체를 생성

- GenericXmlApplicationContext context = new GenericXmlApplicationContext("file: xml 파일 경로");

- context 라는 이름의 객체는 getBean(); 메서드를 이용해 내부 객체 생성
- 의존성 주입이 이미 다 이루어졌기 때문에 결론적으로 사용자는 최종 결과물 하나만 getbean 메서드를 이용해 얻을 수 있음

console: 무대에서 가수가 노래를 합니다.

*연습문제

- 의존 관계에 Broadcast 객체 추가하기

console: 방송 송출용 무대에서 가수가 노래를 합니다.