HibernateExceptionToDataAccessExceptionApsect 구상 중

어제랑 오늘은 회사 이사를 하느라고 공부를 제대로 못하겠네요. 아 삭신이.. 쑤시네요. ㅠ.ㅠ 살이 조금이라도 빠지기를 바라며.. 각설하고 본론으로 들어갑니다.

스프링에서 Hibernate를 사용해서 DAO를 구현하는 방법은 세 가지가 있습니다. 각각은 다음과 같은 특징이 있습니다.

HibernateTemplate

  • JDBC Template과 비슷한 방식이다. 기존 스프링 사용자들에게 가장 익숙한 방법.
  • Session에 직접 접근할 필요가 있을 때는 콜백 메소드를 사용해야 한다.
  • 스프링 클래스를 사용해야만 한다.
  • HibernateDaoSupport를 사용하면 SessionFactory의 세터를 만들 필요가 없다.

Spring 기반 DAO

  • 콜백을 사용하지 않고도 Session에 직접 접근할 수 있다.
  • HibernateDaoSuppoer의 getSession(Boolean)을 사용한다.
  • unchecked exception은 물론이고 checked exception도 던질 수 있다.
  • convertHibernateAccessException()를 사용해서 하이버네이트의 예외를 스프링의 DAE 형태로 바꿀 수 있다. 하지만 try-catch를 해서 다시 던져야 한다.

Hibernate 3 API

  • 하이버 3이 “contextual Sessions”이라는 개념으로 하이버 자체에서 트랜잭션 당 Session 하나를 관리한다.
  • 스프링 코드를 하나도 사용하지 않는다.
  • 엊그제 저녁 토비형이 언급한 부분

Fortunately, Spring’s LocalSessionFactoryBean supports Hibernate’s
SessionFactory.getCurrentSession() method for any Spring transaction
strategy, returning the current Spring-managed transactional Session
even with HibernateTransactionManager. Of course, the standard behavior
of that method remains: returning the current Session associated with
the ongoing JTA transaction, if any (no matter whether driven by
Spring’s JtaTransactionManager, by EJB CMT, or by JTA).

예전에 정리해둔 내용인데 다 까먹었서, 엊그제 토비형이 물어봤는데 이상한 대답을 했습니다. 머리에서 점점 사라져 가는 스프링.. 난 널 원해.. 내 머리에서 나가지 말아죠.

어쨋거나. 세 번째 경우의 DAO의 코드가 가장 심플한데 딱 하나의 단점(?)을 가지고 있습니다. 바로 예외와 관련된 부분인데, 하이버 3.0 부터 Unchecked Exception으로 바꾸긴 했지만, 스프링의 Data Access Exception을 꼭 사용하고 싶을 수도 있겠습니다.

예외 처리가 필요 없거나, 하이버네이트를 매우 많이 사용하는 애플리케이션이라면 그냥 사용하면 되겠지만, 스프링의 DAE를 사용하여 OptimisticLockingFailureException 이런 에러를 잡아 내고 싶다면, 이런 제약 사항이 별로 달갑지 않을 것입니다.

그래서.. 생각 해본 게 바로 HibernateException을 DataAccessException으로 바꿔주는 Aspect입니다. HibernateException이 발생하면, 해당 예외를 잡아서 DataAccessException으로 바꿔서 다시 던지는 역할을 하는 Aspect를 만들고 싶습니다. 재미로..

Apsect 구현은 간단하게 Spring의 @Aspect 를 사용하는 방법과 AspectJ를 사용하여 구현한 다음 Spring과 연동하는 방법이 있는데 전자를 먼저 해보고, 잘 되면 후자를 해보겠습니다.

ps:  설마 이미 누가 만들어 두진 않았겠죠. 간단한거라.. 그랬을 수도 있겠지만 재미삼아 ㄱㄱㅆ

Spring AOP 예제 코드

dn387.zip
사용자 삽입 이미지패키지 구조
aopSchema 에는 aop 스키마 기반의 Spring AOP 예제 코드
aspectAnnotation 에는 @AspectJ 기반의 Spring AOP 예제 코드
aspectJ 에는 Spring에서 AspectJ를 사용하는 예제 코드
classicSpringAOP 에는 Spring 2.0 이전의 Spring AOP 예제 코드가 담겨있습니다.

주의사항
문자열 인코딩은 UTF-8 입니다.
AJDT 플러그인과, Spring IDE 2.0 플러그인을 설치 해주시면 유용합니다.
각 패키지 별로 ~~~Test 라는 클래스를 실행하시면 됩니다.

*위의 소스코드는 AJN에서 제가 진행하고 있는 Spring In Action 세 번째 스터디에서 사용 할 예정입니다.
따라서 자세한 설명은 온라인에서 하지 않습니다. 문의 사항이 있으시면 메일(블로그 바닦에 있습니다.)을 보내 주세요.

2007/09/05 – [Spring In Action/4. Advising beans] – 휴.. Spring AOP와 AspectJ 연동 성공
2007/09/10 – [Spring IDE] – Spring IDE 2.0 활용하기2
2007/07/02 – [Good Tools] – Eclipse 3.3 Europa 설치 뒤 할 일

휴.. Spring AOP와 AspectJ 연동 성공

이전 글의 예상이 맞았습니다.

AspectJ 파일(aj 확장자)을 ajc라는 것으로 컴파일을 해야 하는데 이 녀석을 Eclipse에서는 어떻게 컴파일 할 지 모르기 때문에 컴파일을 못해서 class 파일이 없으니까 결국 Spring 컨테이너는 class 파일이 없어서 AspectJ로 작성한 Aspect를 못 읽어 들이고 에러를 내고 만 것이였습니다.

해결책은 ajc 사용해서 컴파일 해도 되겠지만.. 커맨드 라인에서 무언가를 하는것이 상당히 귀찮은 저 같은 분들은 AJDT 플러그인을 설치하시면 됩니다.

AJDT 홈페이지에 가시면 Eclipse 버전에 따라 release 정보가 표시되어 있습니다.

저는 Eclipse 3.3을 사용하기 때문에 다음의 URL로 업데이트 사이트를 등록하고 플러그인을 설치했습니다.
http://download.eclipse.org/tools/ajdt/33/update

설치한 뒤 해당 프로젝트에 “Convert to AspectJ Project”를 실행해주면 aj 파일은 ajc 사용해서 자동으로 컴파일 해주고, aspecjrt.jar 파일을 클래스패스에 추가해 줍니다.

사용자 삽입 이미지
그럼 Advice가 적용되는 지점에 해당 Advice가 몇 개 적용되는지 보여 줍니다.
사용자 삽입 이미지
멋진 툴입니다.

Class를 못찾던 문제도 해결 됐고 Spring AOP와 AspectJ를 연동도 간단하게 해결되었습니다.

Aspect-Oriented Programming with Spring AOP and AspectJ

Interface 21의 아드리안이 발표한 PPT인것 같습니다. 구글에서 “spring aop aspectj”로 검색했더니 나왔습니다. 굉장히 멋진 발표였을 것 같은데 중간 중간 데모를 못보는 것이 너무 아쉽습니다.

Spring AOP에서 AsepctJ와 연동하는 부분이 막혀서 구글링을 하던 중이였는데 AspectJ의 aj 파일을 컴파일 해서 class 파일로 만들어야 할 것 같습니다. 안그러면 Spring 컨테이너에서 Bean으로 읽어 들일 때 ClassNotFoundException이 떨어지게 됩니다. 물론 그걸 Spring이 잡아서 CannotLoadBeanClassException이라고 좀 더 명확하게 이야기를 해줍니다.ㅋ

2006년 7월에 PPT 파일명을 보니.. Free Seminar… Interface 21에서 무료 세미나도 해주나 봅니다. 우워….. 부럽..
dn345.pdf지만 한국에는 KSUG가 있죠.

Spring AOP APIs

7.1. Introduction

이전 장에서 배운 것은 Spring 2.0에서의 AOP이고 이번에는 좀 더 하위 레벨의 1.2 방식을 알아보겠습니다.

Spring AOP(old) 특징

7.2. Pointcut API in Spring

Pointcut 인터페이스를 구현한 클래스들을 제공하며 이 클래스들을 사용하여 포인트컷을 만들고 재사용할 수 있습니다.

Spring AOP(old) Pointcut
Spring AOP(old) Pointcut Implementation
기선 씨네마 :: Pointcut

7.3. Advice API in Spring

모든 advice는 bean으로 등록하며 per-class와 per-instance 라이프 사이클이 존재합니다.

Spring AOP(old) Advice
기선 씨네마 :: Advice

7.4. Advisor API in Spring

advice와 pointcut을 하나씩 묶어 놓은 것입니다. DefaultPointcutAdvisor  를 사용하여 기본적으로 묶을 수 있습니다.

Spring AOP(old) Advisor

7.5. Using the ProxyFactoryBean to create AOP proxies

ProxyFactoryBean을 사용하여 AOP proxy를 만드는 방법을 설명합니다.

7.6. Concise proxy definitions

중복되는 설정이 많을 때는 parent 속성을 사용하면 좋습니다.

7.7. Creating AOP proxies programmatically with the ProxyFactory

설정이 아닌 코딩을 통해 ProxyFactory를 사용하는 방법입니다.

7.8. Manipulating advised objects

7.9. Using the “autoproxy” facility

매번 ProxyFactoryBean으로 등록하는 것이 아니라 Autoproxy를 사용하면 BeanPostProcessor가 알아서 만들어 줍니다.

Spring AOP(old) ProxyFactoryBean 불편한 점
Autoproxy
BeanNameAutoProxyCreator 사용 예

7.10 Using TargetSources



7.11. Defining new Advice types

7.12. Further resources

JPetStore를 보라고 하는군요.