본문 바로가기
Dev/Java

AOP 개인 저장용

by 펭귄안에 온천 2022. 12. 28.
728x90
반응형

토비의 스프링 6장 드럽게 어렵던데

잊을만 하면 다시 읽어보려고 개인저장용

Aop란 무엇인가?

비즈니스 로직을 담은 UserService에 트랜잭션을 적용해온 과정을 정리해보자.


트랜잭션 서비스 추상화

dao단위의 트랜잭션을 service단위로 변경하기 위해서
비즈니스 로직과, 트랜잭션 경계설정 코드가 함께있는 코드를 작성하니
특정 트랜잭션에 기술이 종속되는 코드가 되어 버리는 문제가 발생했다.

  • JDBC를 사용할때는 로컬 태랜잭션 방식을 적용한 코드
  • JTA를 사용할때는 글로벌/분산 트랜잭션 방식을 적용한 코드

등 어떤것을 사용하느냐에 따라 트랜잭션 적용 코드를 수정해야 하는 일이 생겼다.

그렇기에 트랜잭션과 직접 관련이 없는 코드가 담긴 많은 클래스를 일일이 수정해야 했다.

=> 서비스 추상화 기법 적용

트랜잭션 적용이라는 추상적인 작업 내용은 유지한채로 구현 방법을 자유롭게 바꿀 수 있게 하고
구체적인 구현 내용을 담은 의존 오브젝트는 런타임 시 다이내믹하게 DI를 활용하여 의존성을 주입해주었다.

=> 트랜잭션 방식이 변경해도 비즈니스 로직 코드는 영향을 주지 않음


프록시, 데코레이터 패턴

어떻게 트랜잭션을 처리할지는 추상화를 통해 코드에서 제거했지만,
여전히 비즈니스 로직 코드에서의 트랜잭션을 적용하는 코드는 분리하지 못함

=> 문제는 트랜잭션은 거의 대부분의 비즈니스 로직을 담은 메소드에 필요하다는점
=> 트랜잭션의 코드의 특성 때문에 메소드 추출로 제거할 수 없음

무슨말이냐

try{
    //트랜잭션 시작
    //dao.updateUser();
    //트랜잭션 commit
}catch(){
    //트랜잭션 롤백
}

=> DI를 이요한 데코레이터 패턴 적용으로 해결 가능

클라이언트 -> 프록시 -> 타킷
클라이언트 -> 트랜잭션코드 -> 비즈니스로직코드

트랜잭션을 처리하는 코드는 일종에 데코레이터에 담겨서, 클라이언트와 비즈니스 로직을 담은 다킷 클래스 사이에 존재하도록 함

클라이언트가 일종의 대리자인 프록시 역할을 하는 트랜잭션 데코레이터를 거쳐서 타킷의 접근할 수 있게 함.

=> 비즈니스 로직 코드는 트랜잭션과 같은 성격이 다른 코드로부터 자유로워졌고 독립적으로 로직을 검증할수 있는 고립된 단위 테스트를 만들 수도 있게 됐다.


다이내믹 프록시와 프록시 팩토리 빈

프록시를 이용해서 비즈니스 로직에서 트랜잭션 코드를 분리 할 수 있었지만

프록시 클래스를 만드는 작업이 오히려 큰 짐이 됐다.

트랜잭션 기능을 부여하지 않아도 되는 메소드조차 프록시로서 위임 기능이 필요하기 때문에
일일이 다 구현을 해줘야 했다.

그래서 프록시 클래스 없이도 프록시 오브젝트를 런타임시에 만들어주는 JDK다이내믹 프록시 기술을 활용했다.

덕분에 프록시 클래스의 코드 작성의 부담을 줄었지만 동일한 기능의 프록시를 여러 오브젝트에 적용할 경우 오브젝트 단위로는 중복이 일어나는 문제를 해결하지 못했다.

또한
스프링의 프록시 팩토리 빈을 이용해서 다이내믹 프록시 방법에 DI를 도입했고
부가기능을 담은 어드바이스와 부가 기능 선정 알고리즘 포인트컷은 프록시에서 분리 될 수 있었고
여러 프록시에서 공유해서 사용할 수 있게 했다.


자동 프록시 생성 방법과 포인트컷

트랜잭션 적용 대상이 되는 빈마다 일일이 프록시 팩토리 빈을 설정해줘야 한다는 부담이 남아 있었다.
이를 해결하기 위해 스프링 컨테이너의 빈 생성 후처리 기법을 활용했고
프록시 적용 대상을 패턴을 이용해 선정할 수 있도록,
클래스 선정하는 기능을 당은 포인트컷을 사용했다.


AOP : 애스팩트 지향 프로그래밍

전통적인 객체지향 기술의 설계 방법으로는 독립적인 모듈화가 불가능한 트랜잭션 경계설정과 같은 부가기능을

어떻게 모듈화 할 것인가를 연구해온 사람들은,

이 부가기능 모듈화 작업은 기존의 객체지향 설계 패러다임과 구분되는 새로운 특성이 있다고 생각했다.

그래서 이런 부가 기능 모듈을 객체지향 기술에서 주로 사용되는 오브젝트와는 다르게 특별한 이름으로 부르기 시작했다.

그것이 에스펙트(aspect)다.

애스팩트란 그 자체로 애플리케이션의 핵심 기능을 담고 있지는 않지만, 어플리케이션을 구성하는 중요한 한가지 요소이고, 핵심기능에 부가되어 의미를 갖는 특별한 모듈을 가리킨다.

어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으로 나누어서 보고 그 관점을 기준으로 각각 모듈화하겠다는 것이다

에스펙트는 부가될 기능을 정의한 코드인 어드바이스와,

어드바이스를 어디에 적용할지를 결정하는 포인트컷을 함께 갖고 있다.

에프텍스는 단어 의미대로 어플리케이션을 구성하는 한 가지 측면이라고 생각 할 수 있다.


핵심 기능을 깔끔한 설계를 통해서 모듈화를 할 수 있지만 부가기능이 핵심기능에 침투해 들어가면서 설계와 코드가 지저분해 질 수 있다.

또한 이룬 부가기능 코드는 메소드 여기저기에 흩어져서 중복이 될 수 도 있다.

나름 추상화 를 적용해서 처리를 한다고 하지만 기존의 객체지향 설계 기법으로는 한계가 있다.

이렇게 애플리케이션의 핵심적인 기능에서 부가적인 기능을 분리해서 에스펙트란 도특한 모듈로 만들어서 설계하고

개발하는 방법을 애스팩트(관점) 지향 프로그램 줄여서 AOP라고 부른다.

이름만 들으면 OOP(객체 지향 프로그래밍)과 다른것 처럼 느껴지지만 AOP는 OOP를 돕는 보조적인 기술이지 OOP를 완전히 대체하는 새로운 개념이 아니다.

예를들어 애플리케이션에서 사용자 관리라는 핵심 로직 대신 트랜잭션 경계 설정이라는 관점에서 바라보고 그 부분에서 집중해 설계하고 개발하는것
트랜잭션에 집중하고 싶다면 TransactionAdvice에만 집중하는것,,그리고 그 대상을 결졍해주는 포인트컷 설정에만 신경 쓰는것

이렇게 AOP는 어플리케이션을 특정한 관점을 기준으로 바라볼 수 있게 해준다는 의미다.

반응형

'Dev > Java' 카테고리의 다른 글

String, StringBuilder, StringBuffer의 차이  (0) 2023.05.15
POJO 정리  (0) 2023.02.15
Java reflection Sample Code  (0) 2022.12.16
예외 처리 방법  (0) 2022.11.12
에러(error)와 예외(Exception)의 차이  (0) 2022.11.12