Dependency Injection
Dependency Injection 의존성 주입
Bean 생성범위
싱글톤 빈(Singleton Bean)
스프링 빈은 기본적으로 싱글톤으로 만들어진다.
따라서 컨테이너가 제공하는 모든 빈의 인스턴스는 항상 동일
컨테이너가 항상 새로운 인스턴스를 반환하게 만들고 싶을 경우 scope를 prototype으로 설정
singleton
- 스프링 컨테이너당 하나의 인스턴스 빈만 생성(default)
prototype
- 컨테이너에 빈을 요청할 때마다 새로운 인스턴스 생성
request
- HTTP Request 별로 새로운 인스턴스 생성
session
- HTTP Session 별로 새로운 인스턴스 생성
Spring Bean 설정
XML Document, Annotation, Java Code 메타 정보의 표현 방식
BeanDefinition meta data -> IoC Container
XML Document
XML 문서 형태로 빈의 설정 메타 정보를 기술
단순하며 사용하기 쉽다.
<bean>
태그를 통해 세밀한 제어 가능
Annotation
어플리케이션의 규모가 커지고 빈의 개수가 많아질 경우 XML 파일을 관리하는 것이 번거롭다.
빈으로 사용될 클래스에 특별한 annotation을 부여해 주면 자동으로 빈 등록 가능
'오브젝트 빈 스캐너' 로 '빈 스캐닝'을 통해 자동 등록
기본적으로 클래스의 이름(첫 글자 소문자)을 빈의 아이디로 사용
Annotation으로 빈을 설정할 경우 반드시 <context:componete-scan>
설정 필요
Stereotype annotation
빈 자동 등록에 사용할 수 있는 annotation
빈 자동 인식을 위한 annotation이 여러가지인 이유
- 계층별로 빈의 특성이나 종류를 구분
- AOP Pointcut 표현식을 사영하면 특정 annotation이 달린 클래스만 설정 가능
- 특정 계층의 빈에 부가기능을 부여
@Repository
- Data Access Layer의 DAO 또는 Repository 클래스에 사용
- DataAccessException 자동변환과 같은 AOP의 적용 대상을 선정하기 위해 사용
@Service
- Service Layer의 클래스에 사용
@Controller
- Presentation Layer의 MVC Controller에 사용
- 스프링 웹 서블릿에 의해 웹 요청을 처리하는 컨트롤러 빈으로 선정
@Component
- 위의 Layer 구분을 적용하기 어려운 일반적인 경우에 설정
Dependency Injection
객체 간의 의존관계를 자신이 아닌 외부의 조립기가 수행
제어의 역행(Inversion of Control, IoC) 이라는 의미로 사용
DI를 통해 시스템에 있는 각 객체를 조정하는 외부 개체가 객체들에게 생성시에 의존관계를 주어짐
느슨한 결합(loose coupling)의 주요 강점
객체는 인터페이스에 의한 의존 관계만을 알고 있으며, 이 의존 관계는 구현 클래스에 대한 차이를 모른채 서로 다른 구현으로 대체가 가능
Spring Container가 DI 조립기를 제공
- 스프링 설정 파일을 통하여 객체 간의 의존관계를 설정
- Spring Container가 제공하는 API를 이용하여 객체를 사용
Spring Bean 의존관계 설정 : XML
Application에서 사용할 Spring 자원들을 설정하는 파일
Spring Container는 설정파일에 설정된 내용을 읽어 Application에서 필요한 기능들을 제공
Root tag는 <beans>
파일명은 상관없으며 주로 application.xml, applicationContext.xml 로 지정
기본 설정 - Bean 객체 생성 및 주입
주입 할 객체를 설정파일에 설정
<bean>
: 스프링 컨테이너가 관리할 Bean 객체를 설정
기본 속성
- name : 주입 받을 곳에서 호출 할 이름 설정
- id : 주입 받을 곳에서 호출 할 이름 설정(유일 값)
- class : 주입 할 객체의 클래스
- factory-method : Singleton 패턴으로 작성된 객체의 factory 메소드 호출
기본설정 - Bean 객체 얻기
설정 파일에 설정한 bean을 Container가 제공하는 주입기 역할의 api를 통해 주입 받는다.
Constructor 이용
객체 또는 값을 생성자를 통해 주입 받는다.
<constructor-arg>
: <bean>
의 하위태그로 설정한 bean 객체 또는 값을 생성자를 통해 주입하도록 설정
설정 방법 : <ref>
, <value>
와 같은 하위태그를 이용하여 설정하거나 또는 속성을 이용하여 설정
하위 태그 이용 시
- 객체 주입 시 :
<ref bean = "bean name"/>
- 문자열(String), primitive data 주입 시 :
<value>값</value>
- 값은 기본적으로 String으로 처리, 값의 타입을 명시해야 하는 경우 type 속성 사용
<value type="type">값</value>
- 값은 기본적으로 String으로 처리, 값의 타입을 명시해야 하는 경우 type 속성 사용
- 객체 주입 시 :
속성 이용
- 객체 주입 시 :
<constructor-arg ref="bean name"/>
- 문자열(String), primitive data 주입 시 :
<constructor-arg value="값"/>
- 객체 주입 시 :
Property 이용
property를 통해 객체 또는 값을 주입 받는다. - setter method
주의 : setter를 통해서는 하나의 값만 받을 수 있다.
<property>
: <bean>
의 하위태그로 설정한 bean 객체 또는 값을 Property를 통해 주입하도록 설정
설정 방법 : <ref>
, <value>
와 같은 하위태그를 이용하여 설정하거나 또는 속성을 이용하여 설정
하위 태그 이용 시
- 객체 주입 시 :
<ref bean = "bean name"/>
- 문자열(String), primitive data 주입 시 :
<value>값</value>
- 객체 주입 시 :
속성 이용 : name - 값을 주입할 property 이름(setter의 이름)
- 객체 주입 시 :
<property name = "propertyname" ref = "bean name"/>
- 문자열(String), primitive data 주입 시 :
<property name = "propertyname" value = "값"/>
- 객체 주입 시 :
XML namespace를 이용하여 설정
<bean>
태그의 스키마 설정에 namespace 등록- Bean 설정 시
<bean>
태그의 속성으로 설정 - 기본 데이터 주입 : p:propertyname = "value"
- bean 주입 : p:propertyname-ref="bean_id"
Collection 계열 주입
<constructor-arg>
또는 <property>
의 하위 태그로 Collection 값을 설정하는 태그를 이용하여 값 주입 설정
<list>
: java.util.List, List 계열 컬렉션 값 목록 전달<set>
: java.util.Set, Set 계열 컬렉션 값 목록 전달<map>
: java.util.Map, Map 계열 컬력센에 key-value의 값 목록 전달<props>
: java.util.Properties, Properties에 key(String)-value(String)의 값 목록 전달
<list>
- List계열 컬렉션이나 배열에 값 넣기
<ref>
,<value>
태그를 이용해 값 설정<ref bean="bean_id"/>
: bean 객체를 list에 추가<value [type="type"]>값</value>
: 문자열(String), Primitive값 list에 추가
<set>
- Set계열에 객체 넣기
<value>
,<ref>
를 이용해 값을 넣는다.
<map>
- Map계열 컬렉션에 객체 넣기
<entry>
를 이용해 key-value를 map에 등록
<props>
- java.util.Properties에 값(문자열)넣기
<prop>
를 이용해 key-value를 properties에 등록- 값은 태그 사이에 넣는다.
Spring Bean 의존관계 설정 : Annotation
Annotation : 멤버변수에 직접 정의하는 경우 setter method를 만들지 않아도 됨
@Resource
Spring 2.5부터 지원
멤버변수, setter method에 사용 가능
타입에 맞춰서 연결
JNDI 리소스와 연관지어 생각할 수 있으며, 특정 Bean이 JNDI 리소스에 대한 Injection을 필요로 하는 경우에는 @Resource를 사용할 것을 권장
@Autowired
Spring 2.5부터 지원
Spring에서만 사용 가능
Required 속성을 통해 DI 여부 조정
멤버변수, setter, constructor, 일반 method 사용 가능
타입에 맞춰서 연결
Spring Framework에서 지원하는 Dependency 정의 용도의 Annotation으로, Spring Framework에 종속적이긴 하지만 정밀한 Dependency Injection이 필요한 경우에 유용
동일한 타입의 bean이 여러 개일 경우 @Qualifier("name")으로 식별한다.
@Inject
- Spring 3.0부터 지원
- 특정 Framework에 종속적이지 않음
- Javax.inject-x.x.x.jar 필요
- 멤버변수, setter, constructor, 일반 method 사용 가능
- 이름으로 연결
기타 설정
Factory Method로부터 빈(bean) 생성
- getBean()으로 호출 시 private 생자도 호출하여 객체를 생성
Spring Bean Life Cycle
빈 생성 -> 의존성 주입 -> init-method 실행 -> 빈 사용 -> destroy-method 실행 -> 빈 소멸