끄적끄적 코딩
article thumbnail

IoC (Inversion of Control, 제어의 역행)

- IoC/DI
- 객체지향 언어에서 Object간의 연결 관계를 런타임에 결정
- 객체 간의 관계가 느슨하게 연결됨(loose coupling)
- IoC의 구현 방법 중 하나가 DI(Dependency Injection)

IoC 유형


Dependency Lookup

- 컨테이너가 lookup context를 통해서 필요한 Resource나 Object를 얻는 방식
- JNDI 이외의 방법을 사용한다면 JNDI관련 코드를 오브젝트 내에서 일일이 변경해 주어야 함
- Lookup 한 Object를 필요한 타입으로 Casting 해 주어야 함
- Naming Exception을 처리하기 위한 로직이 필요

Dpendency Injection

- Object에 lookup 코드를 사용하지 않고 컨테이너가 직접 의존 구조를 Object에 설정 할 수 있도록 지정해주는 방식
- Object가 컨테이너의 존재 여부를 알 필요가 없음
- Lookup 관련된 코드들이 Object 내에서 사라짐
- Setter Inejection과 Constructor Inject


Container

Container란?

- 객체의 생성, 사용, 소멸에 해당하는 라이프사이클을 담당
- 라이프사이클을 기본으로 애플리케이션 사용에 필요한 주요 기능을 제공

Container 기능

- 라이프사이클 관리
- Dependency 객체 제공
- Thread 관리
- 기타 애플리케이션 실행에 필요한 환경

Container 필요성

- 비즈니스 로직 외에 부가적인 기능들에 대해서는 독립적으로 관리되도록 하기 위함
- 서비스 look up 이나 COnfiguration에 대한 일관성을 갖기 위함
- 서비스 객체를 사용하기 위해 각각 Factory 또는 Singleton 패턴을 직접 구현하지 않아도 됨

IoC Container

- 오브젝트의 생성과 관계설정, 사용, 제거 등의 작업을 애플리케이션 코드 대신 독립된 컨테이너가 담당.
- 컨테이너가 코드 대신 오브젝트에 대한 제어권을 갖고 있어 IoC라고 부름
- 스프링 컨테이너를 IoC 컨테이너라고 부르기도 함
- 스프링에서 IoC를 담당하는 컨테이너에는 BeanFactory, ApplicationContext가 있음


Spring DI Container

- Spring DI Container가 관리하는 객체르 빈 (Bean) 이라 하고, 이 빈들의 생명주기(Life-Cycle)를 관리하는 의미로 빈 팩토리(BeanFactory)라 한다.
- Bean Factory에 여러 가지 컨테이너 기능을 추가하여 ApplicationContext라 한다.


- Bean을 등록, 생성, 조회, 반환 관리
- 일반적으로 BeanFactory보다는 이를 확장한 ApplicationContext를 사용
- getBean() method가 정의되어 있음

- Bean을 등록, 생성, 조회, 반환 관리기능은 BeanFactory와 같음
- Spring의 각종 부가 서비스를 추가로 제공
- Spring이 제공하는 ApplicationContext 구현클래스는 여러가지 종류가 있음


IoC 개념

객체 제어 방식

- 기존 : 필요한 위치에서 개발자가 필요한 객체 생성 로직 구현
- IoC : 객체 생성을 Container에게 위임하여 처리

IoC 사용에 따른 장점

- 객체 간의 결합도를 떨어뜨릴 수 있음 (loose coupling)

객체간 결합도가 높으면?

- 해당 클래스가 유지보수 될 때 그 클래스와 결합된 다른 클래스도 같이 유지보수 되어야 할 가능성이 높음

객체간 강한 결합

- 클래스 호출 방식
- 클래스내에 선언과 구현이 모두 되어 있기 때문에 다양한 형태로 변화가 불가능


객체 간의 강한 결함을 다형성을 통해 결합도를 낮춤

- 인터페이스 호출 방식
- 구현 클래스 교체가 용이하여 다양한 형태로 변화가능
- 하지만 인터페이스 교체 시 호출 클래스도 수정해야 함


객체 간의 강한 결합을 Factory를 통해 결합도를 낮춤

- 팩토리 호출 방식
- 팩토리 방식은 팩토리가 구현 클래스를 생성하므로 클래스는 팩토리를 호출
- 인터페이스 변경 시 팩토리만 수정하면 됨. 호출 클래스에는 영향을 미치지 않음
- 하지만 클래스에 팩토리를 호출하는 소스가 들어가야함. 그것 자체가 팩토리에 의존함을 의미한다.


객체 간의 강한 결합을 Assembler를 통해 결합도를 낮춤

- IoC 호출 방식
- 팩토리 패턴의 장점을 더하여 어떠한 것 에도 의존하지 않는 형태가 됨
- 실행시점(Runtime)에 클래스 간의 관계가 형성이 됨



Spring DI 용어 정리

빈 (Bean)

- 스프링이 IoC 방식으로 관리하는 오브젝트를 말한다.
- 스프링이 직접 그 생성과 제어를 담당하는 오브젝트만을 Bean이라고 부른다.

빈 팩토리(BeanFactory)

- 스프링이 IoC를 담당하는 핵심 컨테이너
- Bean을 등록, 생성, 조회, 반환하는 기능을 담당
- 일반적으로 BeanFactory를 바로 사용하지 않고 이를 확장한 ApplicationContext를 이용한다.

애플리케이션 컨텍스트(ApplicationContext)

- BeanFactory를 확장한 IoC 컨테이너이다.
- Bean을 등록하고 관리하는 기본적인 기능은 BeanFactory와 동일하다.
- 스프링이 제공하는 각종 부가 서비스를 추가로 제공한다.
- BeanFactory라고 부를 때는 주로 빈의 생성과 제어의 관점에서 이야기하는 것이고, 애플리케이션 컨텍스트라고 할 때는 스프링이제공하는 애플리케이션 지원 기능을 모두 포함해서 이야기하는 것이라고 보면 된다.

설정정보/설정 메타정보(configuration metadata)

- 스프링의 설정정보란 ApplicationContext 도는 BeanFactory가 IoC를 적용하기 위해 사용하는 메타정보를 말한다. 이는 구성정보 내지는 형상정보라는 의미이다.
- 설정정보는 IoC 컨테이너에 의해 관리되는 Bean 객체를 생성하고 구성할 때 사용 됨

스프링 프레임워크

- 스프링 프레임워크는 IoC 컨테이너, ApplicationContext를 포함해서 스프링이 제공하는 모든 기능을 통틀어 말할 때 주로 사용한다.


스프링 Container

 


DI (Dependency Injection)

빈 생성범위

싱글톤 빈 (Singleton Bean)

- 스프링 빈은 기본적으로 ‘싱글톤’으로 만들어짐
- 컨테이너가 제공하는 모든 빈의 인스턴스는 항상 동일함
- 컨테이너가 항상 새로운 인스턴스를 반환하게 만들고 싶을 경우 scope를 prototype으로 설정해야 함


빈의 생성 범위 지정


스프링 빈 설정

- 스프링 빈 설정 메타정보


스프링 빈 설정 : XML

XML 문서

- XML문서 형태로 빈의 설정 메타 정보를 기술
- 단순하며 사용하기 쉬움
- <bean> 태그를 통해 세밀한 제어 가능


스프링 빈 설정 : Annotation

Annotation

- 어플리케이션의 규모가 커지고 빈의 개수가 많아질 경우 XML 파일을 관리하는 것이 번거로움
- 빈으로 사용될 클래스에 특별한 annotation을 부여해 주면 자동으로 빈 등록 가능
- “오브젝트 빈 스캐너”로 “빈 스캐닝”을 통해 자동 등록
  - 빈 스캐너는 기본적으로 클래스 이름을 빈의 아이디로 사용
  - 정확히는 클래스 이름의 첫 글자만 소문자로 바꾼 것을 사용

- Annotation으로 빈을 설정 할 경우 반드시 component-scan을 설정 해야 한다.


Stereotype annotation 종류

- 빈 자동등록에 사용할 수 있는 annotation
- 빈 자동인식을 위한 annotation이 여러가지인 이유
  - 계층별로 빈의 특성이나 종류를 구분
  - AOP Pointcut 표현식을 사용하면 특정 annotation이 달린 클래스만 설정 가능
  - 특정 계층의 빈에 부가기능을 부여


Dependency Injection

- 객체 간의 의존관계를 자신이 아닌 외부의 조립기가 수행
- 제어의 역행(inversion of Control, IoC) 이라는 의미로 사용
- DI를 통해 시스템에 있는 각 객체를 조정하는 외부 개체가 객체들에게 생성시에 의존관계를 주어짐
- 느슨한 결함(loose coupling)의 주요 강점
  - 객체는 인터페이스에 의한 의존 관계만을 알고 있으며, 이 의존 관계는 구현 클래스에 대한 차이를 모르는채 서로 다른 구현으로 대체가 가능

스프링의 DI 지원

- Spring Container가 DI 조립기를 제공
  - 스프링 설정 파일을 통하여 객체 간의 의존관계를 설정
  - Spring Container가 제공하는 API를 이용해 객체를 사용


DI - XML

XML 문서이용

- Application에서 사용할 Spring 자원들을 설정하는 파일
- Spring Container는 설정파일에 설정된 내용을 읽어 Application에서 필요한 기능들을 제공
- Root tag는 <beans>
- 파일명은 상관없다


기본 설정 - 빈 객체 생성 및 주입

주입 할 객체를 설정파일에 설정
- <bean> : 스프링 컨테이너가 관리할 Bean객체를 설정

기본 속성
- name : 주입 받을 곳에서 호출 할 이름 설정
- id : 주입 받을 곳에서 호출 할 이름 설정 (유일 값)
- class : 주입 할 객체의 클래스
- factory-method : Singleton 패턴으로 작성된 객체의 factory 메소드 호출


기본설정 - 빅 객체 얻기
- 설정 파일에 설정한 bean을 Container가 제공하는 주입기 역할의api를 통해 주입 받는다


스프링 빈 의존 관계 설정 - xml

Constructor 이용

객체 또는 값을 생성자를 통해 주입 받는다.
<constructor-arg> : <bean>의 하위태그로 설정한 bean객체 또는 값을 생성자를 통해 주입하도록 설정

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

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

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 nam=”propertyname” ref=”bean name” />
- 문자열(String), primitive data 주입 시 : <property name=”propertyname” value=”값”/>

3. xml namespace를 이용하여 설정

하위태그 이용
- <ref bean=”bean name”/> - 객체 주입 시
- <value>값</value> - 문자열(String), primitive data 주입 시

속성 이용
- <property name=”property name” ref=”bean name”/>
- <property name=”property name” value=”값”/>

XML Namespace를 이용
- <bean> 태그의 스키마 설정에 namespace 등록
- Bean 설정 시 <bean> 태그의 속성으로 설정
* 기본데이터 주입 > p:propertyname=”value”
* bean 주입 > p:propertyname-ref=b”bean_id”


Collection 계열 주입

<constructor-arg> 또는 <property>의 하위 태그로 Collection값을 설정하는 태그를 이용하여 값 주입 설정
설정 태그


<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.utilProperties에 값(문자열) 넣기
- <prop>를 이용해 key-value를 properties에 등록
* 값은 태그 사이에 넣는다. : <prop key=”username”>제티</prop>

DI - annotation

스프링 빈 의존 관계설정 - annotation

Annotation : 멤버변수에 직접 정의 하는 경우 setter method를 만들지 않아도 됨

특정 Bean의 기능 수행을 위해 다른 Bean을 참조해야 하는 경우 사용한다.

@Autowired

- Spring Framework에서 지원하는 Dependency 정의 용도의 Annotation으로, Spring Framework에 종속적이긴 하지만 정밀한 Dependency Injection이 필요한 경우에 유용하다

@Resource

- JSR-250 표준 Annotation으로 Spring Framework 2.5.* 부터 지원하는 Annotation이다. @Resouce는 JNDI 리소스(datasource, java messaging service destination or environment entry)와 연관 지어 생각할 수 있으며, 특정 Bean이 JNDI 리소스 리소스에 대한 Injection을 필요로 하는 경우에는 @Resource를 사용 할 것을 권장한다.

@Inject

- JSR-330 표준 Annotation으로 Spring 3부터 지원하는 Annotation이다. 특정 Framework에 종속되지 않은 애플리케이션을 구성하기 위해서는 @Inject를 사용할 것을 권장한다. @Inject를 사용하기 위해서는 클래스 패스 내에 JSR-330 라이브러리인 javax-inject-x.x.x.jar 파일이 추가되어야 함에 유의해야 한다.

기타 설정

빈 객체의 생성단위
- BeanFactory를 통해 Bean을 요청 시 객체생서의 범위(단위)를 설정
- <bean>의 scope 속성을 이용해 설정
- scope의 값


Factory Method로부터 빈(bean) 생성
- getBean()으로 호출 시 private 생성자도 호출 하여 객체를 생성한다.
- 그러므로 위의 상황에서 factory method만 호출 해야 객체를 얻을 수 있는 것은 아니다.

스프링 빈의 생명 주기 (Life Cycle)

 

'Spring' 카테고리의 다른 글

Spring - REST(Representational State Transfer) API  (0) 2023.05.01
Spring - MyBatis  (0) 2023.05.01
Spring MVC(Model-View-Controller)  (1) 2023.04.20
Spring AOP(Aspect Oriented Programming)  (0) 2023.04.18
Spring Framework  (0) 2023.04.17

검색 태그