Study/Spring

[Spring Framework] 어노테이션을 이용한 DI

AC 2019. 8. 6. 22:15

 

 

스프링에는 크게 XML로 작성된 Bean 정의 파일(이후, Bean 정의 파일)을 이용한 DI, 어노테이션을 이용한 DI, 자바 프로그램(이후 JavaConfig)에 의한 DI가 있다. 여기서는 간단하게 DI를 이용할 수 있는 어노테이션으로 구현하는 방법을 설명한다. 

@Autowired와 @Component

다음 그림을 구현하는 소스 코드 중 인터페이스가 부가된 Service와 Dao의 소스 코드를 살펴보자. (리스트2-1, 리스트2-2, 리스트2-3, 리스트2-4).

 

[리스트 2-1]은 ProductService 인터페이스, [리스트 2-3]은 ProductDao 인터페이스가 있지만 인터페이스에는 아무 조작도 없으므로 따로 설명하지는 않는다.

 

이어서 조작이 필요한 부분, [리스트 2-2]의 ProductServiceImpl 클래스와 [리스트 2-4] ProductDaoImpl 클래스를 살펴보자. 

클래스 선언 앞에 @Component라는 어노테이션(리스트 2-2, 리스트 2-4)이 ProductServiceImpl 클래스의 인스턴스 변수 앞에 @Autowired라는 어노테이션이 추가된 것을 알 수 있다.

 

 

여기에 사용된 @Component와 @Autowried란 무엇일까?
자세한 설명은 나중에 하겠지만, 인스턴스 변수 앞에 @Autowired를 붙이면 DI 컨테이너가 그 인스턴스 변수의 형에 대입할 수 있는 클래스를 @Component가 붙은 클래스 중에서 찾아내 그 인스턴스를 인젝션 해준다.
(정확히는 Bean 정의에서 클래스를 스캔할 범위를 정해야 한다.)

그리고 인스턴스 변수로의 인젝션은 [리스트 2-2] 처럼 접근 제어자가 private라도 인젝션 할 수 있으므로 public void setProductDao(..)와 같은 Setter 메서드를 준비할 필요는 없다. 

만약 @Component가 붙은 클래스가 여러 개 있어도 형이 다르면 @Autowried가 붙은 인스턴스 변수에 인젝션되지 않는다.

이렇게 형을 보고 인젝션하는 방법을 byType이라고 한다.

이상으로 DI의 기본적인 내용을 살펴보았다. 하지만 클래스를 만든 것만으로는 DI를 할 수 없고, XML로 기술된 Bean 정의 파일도 만들어야 한다.
혹은 JavaConfig가 필요할 수도 있다. JavaConfig는 일단 무시하고, 앞에서 설명한 ProductServiceImpl 클래스와 ProductDaoImpl 클래스를 사용한 DI를 구현하기 위한 Bean정의 파일은 다음과 같다.

 

 

Bean 정의 파일을 보면, 파일의 가장 바깥쪽에 beans 태그가 기술되며, 그 beans 태그의 속성으로 XML의 스키마로서 bean과 context라는 두 속성이 선언됐다. 스키마에는 bean과 context 외에도 여러 가지가 있으며, 주요 스키마는 다음 표에서 확인할 수 있다. 덧붙여, Bean 정의 파일의 이름은 관습적으로 applicationContext.xml로 할 때가 많다.


※ 1. Setter 메서드가 없는데도 private인 변수 안을 수정할 수 있는 것은 캡슐화의 정보 은닉에 반하는 것이 아니냐는 논의가 과거에 있었지만, 현재는 편리함에 밀려 그러 논의를 보기가 힘들다.

※ 2. 스키마에는 버전 번호를 표기하지 않는 것이 좋다. 버전 번호를 부여하지 않으면 이용하는 스프링의 버전이 올라가더라도 Bean 정의 파일을 수정할 필요가 없어진다.

- 버전 번호가 있는 경우 : http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
- 버전 번호가 없는 경우 :  http://www.springframework.org/schema/beans/spring-beans.xsd

 

 

스키마에 이어서 기술되는 태그 (리스트2-5)는 @Autowried와 @Component를 구현하기 위한 태그이다.

일단 이것으로 어노테이션을 이용한 DI를 구현할 수 있다.

 

 

 

LIST