본문 바로가기

개발&컴퓨터/개발강좌

스프링(Spring) 프레임워크 기본 개념 강좌 (2) - 주요 구성 요소 & DI

반응형

1. 스프링의 핵심 개념

 * DI

 * IoC

 * AOP & AOP Proxy

 * AOP in Spring

 

 1) 주요 구성 요소 

 * IoC / DI

 * AOP

 * PSA

 

 

 

 

- 용어 설명 -

* Plain Old Java Object 혹은 POJO는 처음에 javax.ejb 인터페이스를 상속받지 않은, 무거운 EJB와는 반대로 경량의 자바 객체를 지칭하는 용어로 소개. 즉, POJO라는 이름은 특별하지도 않고, 특히 Enterprise JavaBean이 아닌 자바 객체를 강조하는 의미로 사용.

 이 이름은 Martin Fowler, Rebecca Parsons와 Josh MacKenzie에 의해 2000년 9월에 만들어졌으며, 프레임워크에 종속된 복잡한 객체에 반대되는 간단한 객체를 설명하기 위한 용어의 필요성이 많아짐에 따라 POJO라는 이름이 점점 널리 쓰여짐.

 POJO 대표적인 예로, JavaBean을 들 수 있는데, JavaBean은 기본 생성자와 멤버 필드에 접근할 수 있는 getter/setter 메소드를 가진 serializable(직렬화가 가능한)한 객체를 의미. POJO를 이용한 디자인이 널리 쓰임에 따라 POJO를 기본으로 하는 스프링이나 하이버네이트와 같은 프레임워크에서도 생겨남. 요즘에는 POJO는 (EJB 뿐만 아니라) 별도로 종속되지 않는 자바 객체를 통칭하여 의미한다.

 

* PSA (Portable Service Abstractions) – (쉬운) 서비스 추상화
 성격이 비슷한 여러 종류의 기술을 추상화하고 이를 일관된 방법으로 사용할 수 있도록 지원.
 트랜잭션 서비스 추상화 : 여러 가지의 DB를 사용한다고 하면 Global Transaction 방식을 사용.
 자바는 JDBC 외에 이런 글로벌 트랜잭션을 지원하는 트랜잭션 매니져를 지원하기 위한 API인 JTA(Java Transaction Api)를 제공.
 높은 응집도와 낮은 결합도를 준수.

 

 

 2) DI (Dependency Injection, 의존성 주입)

  DI는 스프링(Sping)을 통해서 특별히 생겨난 용어는 아님. DI를 잘 지원해주는게 스프링.

 

* 일체형

 

 - Composition : HAS-A 관계

 - A가 B를 생성자에서 생성하는 관계 .

 

 

 

 

* 분리 / 도킹(부착) 형

 - Association 관계

 - A객체가 다른 녀석이 만든 B 객체를 사용. 

 

 

예제 설명

A를 스마트폰, B를 배터리리라 하면,

일체형 스마트폰 (아이폰)은 바로 전원을 켜도 되지만,

배터리 탈부착 형태의 스마트폰 (갤럭시S)은 여기서는 배터리를 넣고, 전원을 넣어야 함.

 

일체형은 A라는 객체의 내부 프로세스에 대해 신경 쓸 필요가 없으며, 분리형은 A와 B를 개별적으로 세팅해 주어야 함. 단, 분리형은 내가 원하는 것(다른 배터리)으로 바꾸어 부착할 수 있음. 이것을 DI의 개념이라 보면 됨.

 

 

위의 예제 처럼 분리/도킹(부착) 형으로 개발을 하게 되면 각 객체(또는 애플리케이션) 간의 결합도를 낮출 수 있으며, DI를 사용하는 목적이 이러한 결합도를 낮추기 위함.

 

 

 2-1) DI의 종류

  * Setter Injection (세터 주입)

  * Construction Injection (생성자 주입)

 

 

Setter Injection

 B b = new B();

 A a = new A();

 a.setB(b);

 

 

Construction Injection

 B b = new B();

 A a = new A(b);

 

 

 위의 코드는 JAVA 개발자라면 친숙한 개념으로 DI는 JAVA에서도 많이 사용해 왔던 개념. (객체 지향 프로그래밍(OOP)에 있던 개념)
 단지, 스프링에서는 이러한 일련의 과정을 (동적으로) 자동화 함.


 

 2-2) 스프링에서의 DI

 * 명세서에 따라서 자동적으로 부품을 활용하여 제품을 조립 => 스프링

 

 * 일체형 프로그램과는 반대로 제품을 생성.

 * 즉, 작은 부품부터 시작하여 큰 부품으로 이동하며 조립.
 => Inversion of Control (IoC)

 

기본적인 완제품 제작 순서와는 다르게 작은 부품부터 큰 부품으로, 제품을 만드는 순서가 역순 (Inversion of Control).
그래서 IoC라는 이름이 붙었으며, 이러한 일련의 작업을 스프링은 컨테이너라는 곳에 담아서 처리하여 스프링을 IoC컨테이너라 함.

스프링은 완성품을 만드는 것보다 부품을 모아서 조립하는 것을 도와줌. 즉, 이러한 DI 구조를 개발자가 좀 더 쉽고, 간편하게 사용할 수 있도록 지원해 주는 프레임워크 중의 하나가 스프링.


 

 스프링에서의 DI의 의미

- 부품들을 생성하고, 제품을 조립해주는 공정과정을 대신해 주는 라이브러리 (역할자)

 

 * 개발 핵심 처리 루틴의 수정 없이 제품(객체)를 다른 제품(객체)로 쉽게 대체하여 생성 가능하도록 하는 역할을 함.

 * 명세서에 따라서 자동적으로 부품을 활용하여 제품을 조립.

 * 생성하기 원하는 객체를 명세서(XML)에 기술하고, 그 부품과 의존성(Dependency)들을 보관하는 일을 처리. 그러한 데이터를 보관하는 공간을 컨테이너라 함. (IoC 컨테이너)

 

제품 

스프링 

 주문서

 설정파일(XML) 

 일반적은 순서의 공정

 역방향 조립 

 

 

2-3) DI 구현

 

 객체의 생성과 도킹에 대한 내용이 소스 코드 상에 있는 것이 아닌 별도의 텍스트 파일(XML 설정 파일)에 분리하여 존재.
 (JAVA소스 컴파일 없이 XML 변경만으로 내용 변경 가능)

 

JAVA(DI) : Property 항목은 실제 값을 record에 바로 주입하는 것이 아닌 setRecord() 함수를 호출하여 주입함.

 JAVA (DI)

Record record = new SprRecord();

RecordView view = new SprRecordView();

view.setRecord(record); // Injection

view.input();

view.print();

 

 

XML (스프링 DI) : 객체 생성 시, 패키지명을 포함한 풀 클래스 네임 작성.

XML에 작성된 명세서를 보고, IoC컨테이너가 각 객체를 생성하고, 값을 주입해줌.

여기서 ApplicationContext 가 IoC컨테이너 역할을 함.

XML (스프링 DI) config.xml

<bean id=“record” class=“di.SprRecord”></bean> // 빈 객체 생

<bean id=“view” class=“di.SprRecordView”> // 빈 객체 생성

  <property name=“record” ref=“record”></property> // setRecord() 호출 

</bean>

 • JAVA

// XML을 파싱하여 컨테이너에 담는 작업

ApplicationContext ctx = new ClassPathXmlApplicationContext(“config.xml”);

RecordView = (RecordView) ctx.getBean(“view”);

 

 

 * XML을 활용(스프링 DI)하는 경우는 VIEW에 대한 객체만을 요청했을 뿐, 실제 내부적인 사항은 JAVA코드 상에 드러나지 않음.
 * 새로운 클래스의 bean객체를 만들어 XML에 주입만 시켜줘도, 기존 소스 변경 없이 새로운 형태의 객체 적용이 가능함.

 

 

2-4) XML (Bean) Sample

 

* 빈(Bean) 객체는 반드시 클래스를 사용. 인터페이스나 추상클래스는 객체 생성이 불가능함.
* 빈 객체 생성, 객체 초기화, 객체 값(또는 레퍼런스) 주입.

 

XML (스프링 DI) config.xml

 

1)
<bean id=“record” name=“r1,r2 r3;r4” class=“di.SprRecord”>
    <property name=“kor” value=“20”></property>
</bean>

2)

<bean id=“record” name=“r1,r2 r3;r4” class=“di.SprRecord”>
    <constructor-arg value=“20”></constructor-arg>
</bean>

3)

<bean id=“record” name=“r1,r2 r3;r4” class=“di.SprRecord”>
    <constructor-arg name=“kor” value=“20”></constructor-arg>
</bean>

4)

<bean id=“record” ” name=“r1,r2 r3;r4” class=“di.SprRecord”
    p:kor=“50” p:eng=“60” p:math=“70”>

5)

<bean id=“view” class=”di.SprRecordView”>
    <property name=“record” ref=“record”></property>
</bean>
 

id : 빈 객체 고유 이름 (접근 가능자)

name : 객체의 이름(별칭)

class : 생성할 클래스

constructor-arg : 초기값 설정 (생성자 함수 사용)

property : 초기값 설정 (Setter함수 사용)

 

1) 이름이 record인 빈 객체 생성 / 별명 4개 : r1,r2,r3,r4 / SprReocrd 클래스 객체 생성.

    초기값으로 kor 라는 프로퍼티에 20값 대입 (set함수가 존재해야 위와 같은 프로퍼티 설정이 가능).
2) 이름이 record인 빈 객체 생성 / 생성자(인자가 하나인)를 통해서 값 대입 & 생성.
3) 생성자 중에서 kor 값을 입력받는 생성자를 통해서 20값 대입하고, 생성.
4) 3개의 인자를 받는 생성자를 통해 kor = 50, eng = 60, math = 70 대입 & 생성.
5) 생성된 record 객체를 set함수를 통해 프로퍼티에 저장하고 SprRecordView를 생성.

 

참고로 값을 대입하는 경우에는 value, 참조(레퍼런스)를 대입하는 경우에는 ref 를 사용.

 

 

반응형