토비 7장 스프링 핵심기술의 응용
< 7.1 SQL과 DAO의 분리 >
- 목적 : 현실적으로 SQL의 변경작업은 빈번히 일어난다.
SQL을 적절히 분리해 DAO코드와 다른 파일이나 위치에 두고 관리할 수 있도록 한다.
1. XML 설정을 이용한 분리
- 가장 손쉽게 생각해볼 수 있는 SQL분리 방법은 SQL을 스프링의 XML설정파일로 빼내는 것
a. 개별 SQL 프로퍼티 방식
- SQL를 프로퍼티로 만들고 이를 XML에서 지정하도록 하는 방식
- 매번 새로운 SQL이 필요 할 때마다 프로퍼티를 추가하고, DI를 위한 변수와 수정자 메소드를 만들어줘야 해서 안좋음
b. SQL 맵 프로퍼티 방식
- SQL을 MAP에 담는 방식 (KEY, VALUE)
- Map은 하나 이상의 복잡한 정보를 담고 있기 때문에 <property>태그의 애트리 뷰트로는 정의할 수 없다.
2. SQL 제공 서비스
위와 같은 방법들이 있지만 좋지 않다.
SQL을 따로 분리해둬야 독립적으로 SQL 문의 리뷰나 SQL 튜닝 작업을 수행하기가 편하다.
즉, 독립적인 SQL 제공 서비스가 필요하다.
a. SQL 서비스 인터페이스
- 클라이언트인 DAO를 SQL 서비스의 구현에서 독립적으로 만들도록 인터페이스를 사용하고,
DI로 구현 클래스의 오브젝트를 주입해주어야 한다. (그동안 했던 내용 )
- SqlService인터페이스 : String interface SqlService
- UserDaoJdbc 클래스 : sqlService 를 이용해 SQL조회
b. 스프링 설정을 사용하는 단순 SQL서비스
- SqlService구현체 : SimpleSqlService 클래스를 빈으로 등록하고 UserDao가 DI 받아 사용하도록 설정한다.
- 여기까지 DI구조를 활용할 수 있는 기본적인 준비 끝
< 7.2 인터페이스의 분리와 자기참조 빈 >
- SqlService 인터페이스로 대표되는 기능을 구현 방법과 확장 가능성에 따라
유연한 방법으로 재구성 할 수 있도록 설계필요
1. XML 파일 매핑
- SQL을 저장해두는 전용 포맷을 가진 독립적인 파일을 이용하는게 좋다. 가장 편리한 포맷은 XML
- 이 XML파일에서 SQL을 읽어뒀다가 DAO에게 제공해주는 SQL 서비스 구현 클래스를 만들어보자
JAXB를 이용해 XML문서를 변환하는 방법이 있다. (XML문서에서 SQL을 가져올때 사용)
JAXB ( Java Architecture for XML Binding )
- 가장 간단하게 사용할 수 있는 XML에 담긴 정보를 파일에서 읽어오는 방법
- XML 문서정보를 거의 동일한 구조의 오브젝트로 직접 매핑해주는 것
- XML문서의 구조를 정의한 스키마를 이용해서, 매핑할 오브젝트의 클래스까지 자동으로 만들어주는 컴파일러를 제공한다.
- SQL 정보는 key 와 SQL의 목록으로 구성된 맵 구조로 만들어드면 편리하다.
- 언마샬링 : XML문서를 읽어서 자바의 오브젝트로 변환하는 것
- 마샬링 : 반대로 바인딩 오브젝트를 XML문서로 변환하는 것
2. XML 파일을 이용하는 SQL 서비스
- 특별한 이유가 없는 한 XML 파일은 한번만 읽도록 해야한다.
- 생성자에서 JAXB를 이용하여 XML로 된 SQL 문서를 읽어들이고,
변환된 SQL오브젝트들을 맵으로 옮겨서 저장해뒀다가,
DAO의 요청에 따라 SQL을 찾아서 전달하는 방식으로 sqlService 구현.
3. 빈의 초기화 작업
- 생성자에서 예외가 발생할 수 있는 복잡한 초기화 작업을 다루는 것은 좋지않다.
- 초기상태를 가진 오브젝트를 만들어놓고 별도의 초기화 메서드를 사용하는 것이 바람직하다.
- 빈후처리기 : 스프링 컨테이너가 빈을 생성한 뒤에 부가적인 작업을 수행할 수 있게 해주는 특별한 기능
-- 여기부터 서로 관심이 다른 코드들을 분리하고, 서로 코드에 영향을 주지 않으면서 유연하게 확장 가능하도록 DI를 적용한다.
4. 변화를 위한 준비 : 인터페이스 분리
- 분리 가능한 관심사를 구분한다.
1) SQL 정보를 외부의 리소스로부터 읽어오는 것
2) 읽어온 SQL을 보관하고 있다가 필요할때 제공하는 것
- 전략패턴을 적용해 별도의 오브젝트로 분리해야한다.
- SqlService의 구현 클래스가 변경가능한 책임을 가진 SqlReader와 SqlRegistry 두가지 타입의 오브젝트를 사용하게 만든다. 당연히 인터페이스를 이용하게 하고 DI를 통해 의존 오브젝트를 제공받게 해야한다.
5. 자기참조 빈으로 시작하기
- XmlSqlService 클래스 안에 혼재되어 있던 성격이 다른 코드를
세가지 인터페이스를 구현하는 방법을 통해 분리한다.
- 클래스도 하나뿐이고 빈도 하나만 등록할 것이지만, 마치 세 개의 빈이 등록된 것처럼 SqlService 빈이 SqlRegistry와 SqlReader를 주입받도록 만들어야 한다.
- 스프링은 프로퍼티의 ref항목에 자기 자신을 넣는것을 허용한다.
- 인터페이스를 사용하고 DI를 이용하면 특별한 구조까지 유연하게 구성이 가능하다.
- 자기참조 빈을 만들어보는 것은, 책임과 관심사가 복잡하게 얽혀 있어서 확장이 힘들고 변경에 취약한 구조의 클래스를 유연한 구조로 만들려고 할 때 처음 시도해볼 수 있는 방법이다.
----------------------------------------------------
여기까지 인터페이스를 정의하고, 인터페이스에 따라 메소드를 구분해서 DI가 가능하도록 코드를 재구성하는데 성공했다. 다음은 이를 완전히 분리해두고 DI로 조합해서 사용하게 만드는 단계
----------------------------------------------------
6. 디폴트 의존 관계
b. 디플트 의존관계를 갖는 빈 만들기
- BaseSqlService는 sqlReader와 sqlRegistry 프로퍼티의 DI를 통해 의존관계를 자유롭게 변경해가면서 기능을 확장할 수 있다. 유연성을 보장하려면 이런 구조가 꼭 필요하지만, 적어도 3개의 빈을 등록해줘야 한다는 점이 귀찮게 느껴지기도 한다.
- 특정 의존 오브젝트가 대부분의 환경에서 거의 디폴트라고 해도 좋을만큼 기본적으로 사용될 가증성이 있다면, 디폴트 의존관계를 갖는 빈을 만드는 것을 고려해볼 필요가 있다.
- 디폴트 의존관계란 : 외부에서 DI받지 않는 경우 기본적으로 자동 적용되는 의존관계를 말한다.
< 7.3 서비스 추상화 적용 >
- 자바에는 JAXB외에도 다양한 XML가 자바오브젝트를 매핑하는 기술이 있다.
필요에 따라 다른 기술로 손쉽게 바꿔서 사용할 수 있게 해야한다.
- XML 파일을 좀 더 다양한 소스에서 가져올 수 있게 만든다.
1.OXM 서비스 추상화
해당 장은 JAXB로 구현된 소스를 Castor로 바꿔주는 예제로 설명한다.
- OXM (Object - XML Mapping )
: XML과 자바오브젝트를 매핑해서 상호 변환해주는 기술
JAXB외에도 여러개 존재 (Castor XML, JiBX, XmlBeans, Xstream)
- OXM프레임워크와 기술들은 기능 면에서 상호 호환성이 있다.
기능이 같은 여러가지 기술이 존재한다는 이야기가 나오면 서비스 추상화.
- 로우레벨의 구체적인 기술과 API에 종속되지 않고, 추상화된 레이어와 API를 제공해서 구현 기술에 대해 독립적인 코드를 작성할 수 있게 해주는 서비스 추상화가 필요하다.
- 스프링은 트랜잭션, 메일전송뿐 아니라 OXM에 대해서도 서비스 추상화 기능을 제공한다.
- 스프링이 제공하는 OXM 추상화 서비스 인터페이스는 마샬러와 언마샬러가 있다
- 위에 마샬링, 언마샬링 참고.
- 서비스 추상화는 이렇게 로우레벨의 기술을 필요에 따라 변경해서 사용하더라도 일관된 어플리케이션 코드를 유지할 수 있게 해준다.
2. OXM 서비스 추상화 적용
- 이제 스프링의 OXM 추상화 기능을 이용하는 SqlService를 만들어보자
- SQL을 읽는 방법을 OXM으로 제한해서 사용성을 극대화하는게 목적이다.
a. 멤버 클래스를 참조하는 통합 클래스
b. 위임을 이용한 BaseSqlService의 재사용
3. 리소스 추상화
a. 리소스
b. 리소스 로더
c. Resource를 이용해 XML 파일 가져오기
4. 인터페이스 상속을 통한 안전한 기능확정
'책 > 토비 스프링 2020' 카테고리의 다른 글
(토비의 스프링) 1. 오브젝트와 의존관계 (IoC/DI ) (0) | 2019.12.18 |
---|---|
(토비의 스프링) 1. 오브젝트와 의존관계 (DAO의 분리와 확장) (0) | 2019.12.18 |
[2017] 6. AOP (0) | 2018.01.04 |
[2017] 5. 서비스추상화 (0) | 2017.12.29 |
[2017] 스프링개념 (0) | 2017.12.28 |