Back-End/Spring Framework

Dependency Injection

good_da22 2022. 10. 19. 23:28

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>와 같은 하위태그를 이용하여 설정하거나 또는 속성을 이용하여 설정

  1. 하위 태그 이용 시

    • 객체 주입 시 : <ref bean = "bean name"/>
    • 문자열(String), primitive data 주입 시 : <value>값</value>
      • 값은 기본적으로 String으로 처리, 값의 타입을 명시해야 하는 경우 type 속성 사용 <value type="type">값</value>
  2. 속성 이용

    • 객체 주입 시 : <constructor-arg ref="bean name"/>
    • 문자열(String), primitive data 주입 시 : <constructor-arg value="값"/>

Property 이용

property를 통해 객체 또는 값을 주입 받는다. - setter method

주의 : setter를 통해서는 하나의 값만 받을 수 있다.

<property> : <bean>의 하위태그로 설정한 bean 객체 또는 값을 Property를 통해 주입하도록 설정

설정 방법 : <ref>, <value>와 같은 하위태그를 이용하여 설정하거나 또는 속성을 이용하여 설정

  1. 하위 태그 이용 시

    • 객체 주입 시 : <ref bean = "bean name"/>
    • 문자열(String), primitive data 주입 시 : <value>값</value>
  2. 속성 이용 : name - 값을 주입할 property 이름(setter의 이름)

    • 객체 주입 시 : <property name = "propertyname" ref = "bean name"/>
    • 문자열(String), primitive data 주입 시 : <property name = "propertyname" value = "값"/>
  3. 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 실행 -> 빈 소멸