AOP (3)

 

 

 

 

 

 

❑ 타입별 Advice

 

 

➤ Advice 순서

 

어드바이스는 기본적으로 순서를 보장하지 않는다.

순서를 지정하라면 @Aspect 적용 단위로 org.springframework.core.annotation.@Order 애너테이션을 적용하면 됨

  • 어드바이스 단위가 아닌 클래스 단위로 적용할 수 있다.
  • 하나의 aspect에 여러 어드바이스가 존재하면 순서를 보장받을 수 없다.

aspect를 별도의 클래스로 분리해야 한다.

 

 

 

➤ Advice 종류

 

 

▶️ Before

  • join point 실행 이전에 실행한다.
  • Before Advice 구현한 메서드는 일반적으로 리턴 타입이 void 이다.
  • 메서드에서 예외를 발생시킬 경우 대상 객체의 메서드가 호출되지 않는다.
  • 작업 흐름을 변경할 수 없다.

 

 

▶️ After returning

  • join point가 정상 완료된 후 실행한다.
  • returning 속성에 사용된 이름은 advice 메서드의 매개변수 이름과 일치해야 함

 

 

▶️ After throwing

  • 메서드가 예외를 던지는 경우에 실행한다.
  • 메서드 실행이 예외를 던져서 종료될 때 실행한다.
  • throwing 속성에 사용된 이름은 advice 메서드의 매개변수 이름과 일치해야 함

 

 

▶️ After (finally)

  • join point의 동작(정상 또는 예외)과는 상관없이 실행한다.
  • 메서드 실행 후 공통 기능을 실행한다.
  • try~finally의 finally를 생각하면 된다.
  • 일반적으로 리소스를 해제하는데 사용한다.

 

 

▶️ Around ⭐️

  • 메서드 호출 전후에 수행하며 가장 강력한 advice이다.
  • 메서드 실행 전후, 예외 발생 시점에 공통 기능을 실행한다.
    • 조인 포인트 실행 여부 선택 - joinPoint.proceed()
    • 전달 값 변환 - joinPoint.proceed(args[])
    • 반환 값 변환
    • 예외 변환
  • try~catch~finally 가 들어가는 구문 처리가 가능하다.
  • 어드바이스의 첫 번째 매개변수는 ProceedingJoinPoint를 사용해야 한다.
  • proceed()를 통해 대상을 여러번 실행할 수 있다.

 

 

@Around만 있어도 모든 기능 수행이 가능하다!

하지만 target등 고려해야할 사항이 있을 때 정상적으로 작동되지 않는 경우도 있다.

@Before, @After 어드바이스는 기능은 적지만 원하는대로 작동되고 코드도 단순하다.

 

좋은 설계는 @Around만 사용해서 모두 해결하는 것보다는 제약을 가지더라도 실수를 미연에 방지하는 것이다.

제약을 두면 문제 자체가 발생하지 않고 역할이 명확해진다.

 

 

 

 

 

❑ Pointcut 표현식

 

 

➤ 포인트컷과 표현식&지시자

 

▶️ 포인트컷

관심 조인 포인트를 결정

어드바이스가 실행되는 시기를 제어

AspectJ는 포인트컷을 편리하게 표현하기 위한 표현식을 제공

ex) @Pointcut(“execution(* hello.aop.order..*(..))”)

 

 

▶️ 포인트컷 지시자(Pointcut Designator, PCD)

 

포인트컷 지시자 종류

종류 설명
excution 메서드 실행 조인트 포인트를 매칭한다. 스프링 AOP에서 가장 많이 사용하며, 기능도 복잡하다
within 특정 타입 내의 조인포인트를 매칭한다
args 인자가 주어진 타입의 인스턴스인 조인 포인트
this 스프링 객체(스프링 AOP proxy) 대상으로 하는 조인 포인트
target Target 객체(스프링 AOP proxy 가르키는 실제 대상) 대상으로 하는 조인 포인트
@target 실행 객체의 클래스에 주어진 타입의 애너테이션이 있는 조인 포인트
@within 주어진 애너테이션이 있는 타입 조인 포인트
@annotation 메서드가 주어진 애너테이션을 가지고 있는 조인 포인트를 매칭
@args 전달된 실제 인수의 런타임 타입이 주어진 타입의 애너테이션을 갖는 조인 포인트
bean 스프링 전용 포인트컷 지시자, 빈의 이름으로 포인트컷을 지정한다.

 

 

 

➤ Pointcut 표현식 결합

 

&&, ||, ! 를 사용하여 결합할 수 있다.

이름으로 포인트컷 표현식을 참조할 수도 있다.

 

 

▶️ 일반적인 pointcut 표현식들

 

// 모든 공개 매서드 실행
execution(public * *(..))

// set 다음 이름으로 시작하는 모든 메서드 실행
execution(* set*(..))

// AccountService 인터페이스에 의해 정의된 모든 메서드의 실행
execution(* com.xyz.service.AccountService.*(..))

// service 패키지에 정의된 메서드 실행
execution(* com.xyz.servic.*.*(..))

// service 패키지 또는 해당 하위 패키지 중 하나에 정의된 메서드 실행
execution(* com.xyz.service..*.*(..))



// Spring AOP에서만 메서드 실행하는 표현식들

// service 패키지 내의 모든 조인 포인트
within(com.xyz.service.*)

// service 패키지 또는 하위 패키지 중 하나 내의 모든 조인 포인트
within(com.xyz.service..*)

// AcountService 프록시가 인터페이스를 구현하는 모든 조인 포인트
this(com.xyz.service.AccountService)

// AcountService 대상 객체가 인터페이스를 구현하는 모든 조인 포인트
target(com.xyz.service.AccountService)

// 단일 매개변수를 사용하고 런타임에 전달된 인수가 Serializable 과 같은 모든 조인포인트
args(java.io.Serializable)

// 대상 객체가 @Transactional 애너테이션이 있는 조인 포인트
@target(org.springframework.transaction.annotation.Transactional)

// 실행 메서드에 @Transactional 애너테이션이 있는 조인 포인트
@annotation(org.springframework.transaction.annotation.Transactional)

// 단일 매개 변수를 사용하고 전달된 인수의 런타임 유형이 @Classified 애너테이션을 갖는 조인 포인트
@args(com.xyz.security.Classified)

// tradeService 라는 이름을 가진 스프링 빈의 모든 조인 포인트
bean(tradeService)

// 와일드 표현식 *Service 라는 이름을 가진 스프링 빈의 모든 조인 포인트
bean(*Service)

 

 

 

 

 

❑ JoinPoint

 

 

➤ AOP 적용 위치

 

  • AOP는 메서드 실행 위치 뿐만 아니라 다양한 위치에 적용할 수 있다.
  • 적용 가능 지점 : 생성자, 필드 값 접근, static 메서드 접근, 메서드 실행
  • AOP 를 수행하는 메서드는 이 JoinPoint 인스턴스를 인자로 받게 된다.
  • JointPoint 인스턴스에서 조인 포인트의 정보를 얻어내야 한다.

 

 

➤ JoinPoint

 

  • AOP를 적용할 수 있는 지점을 의미하는 추상적 개념
  • 프로그램 실행 중 지점을 나타낸다.
  • AspectJ를 사용해서 컴파일 시점과 클래스 로딩 시점에 적용하는 AOP는 바이트코드를 실제 조작하기 때문에 해당 기능을 모든 지점에 적용할 수 있다.
  • 프록시 방식을 사용하는 Spring AOP메서드 실행 지점에만 AOP를 적용할 수 있다.
  • 프록시는 메서드 오버라이딩 개념으로 동작한다.
  • 생성자나 static 메서드, 필드값 접근에는 프록시 개념이 적용될 수 없다. (프록시는 스프링 AOP에서 사용하기 때문)
  • 프록시를 사용하는 스프링 AOP의 조인 포인트는 메서드 실행으로 제한된다.
  • 프록시 방식을 사용하는 스프링 AOP는 스프링 컨테이너가 관리하는 스프링 빈에만 AOP를 적용할 수 있다.
  • JoinPoint 메서드는 advice의 종류에 따라 사용방법이 다르지만 기본적으로 advice 메서드에 매개변수로 선언만 하면 된다.

 

 

 

➤ JoinPoint Interface의 주요 기능

 

  • JoinPoint.getArgs() : JoinPoint에 전달된 인자를 배열로 반환한다.
  • JoinPoint.getThis() : AOP 프록시 객체를 반환한다.
  • JoinPoint.getTarget() : AOP가 적용된 대상 객체를 반환한다. (클라이언트가 호출한 비즈니스 메서드를 포함하는 비즈니스 객체를 반환)
  • JoinPoint.getSignature() : advice되는 메서드에 대한 설명을 반환한다.
  • JoinPoint.toString() : advice되는 방법에 대한 유용한 설명을 인쇄한다.

 

 

➤ ProceedingJoinPoint Interface의 주요 기능

 

▶️ ProceedingJoinPoint Interface

얜 또 뭐야...

https://www.javadoc.io/doc/org.aspectj/aspectjrt/1.7.2/org/aspectj/lang/ProceedingJoinPoint.html

 

ProceedingJoinPoint - aspectjrt 1.7.2 javadoc

Latest version of org.aspectj:aspectjrt https://javadoc.io/doc/org.aspectj/aspectjrt Current version 1.7.2 https://javadoc.io/doc/org.aspectj/aspectjrt/1.7.2 package-list path (used for javadoc generation -link option) https://javadoc.io/doc/org.aspectj/as

www.javadoc.io

 

JoinPoint 인터페이스를 extends하는 인터페이스 이다
  • proceed() : 다음 어드바이스나 타겟을 호출한다.

 

 

 

 

❑ 애너테이션(Annotation)을 이용한 AOP

 

 

➤ Spring에서의 AOP

 

AOP는 스프링 IoC를 보완하여 매우 강력한 미들웨어 솔루션을 제공한다.

 

▶️ Spring AOP 지원

  • @AspectJ 애너테이션 스타일
  • 스키마 기반 접근

 

 

▶️ @AspectJ 지원

 

  • @AspectJ는 애너테이션이 있는 일반 자바 클래스로 aspect를 선언하는 스타일을 말한다.
  • AspectJ 5 릴리스의 일부로 AspectJ 프로젝트에 의해 도입되었다.
  • 스프링은 pointcut 구문 분석 및 일치를 위해 AspectJ가 제공하는 라이브러리를 사용하여 AspectJ 5와 동일한 애너테이션을 해석한다.
  • AOP 런타임은 여전히 순수한 스프링 AOP이며, AspectJ 컴파일러 위버(weaver)에 의존하지 않는다.

 

 

▶️ @AspectJ 지원 활성화

 

  • Spring 설정에서 @AspectJ 에 기반한 Spring AOP 설정과 이러한 aspect에 의해 advice되는 자동 프록시 빈에 대한 Spring 지원을 활성화 해야한다.
  • @AspectJ 지원은 XML 또는 Java 스타일 설정으로 활성화할 수 있다.
  • Java 설정으로 @AspectJ 지원 활성화 방법
@Configuration
@EnableAspectJAutoProxy
public class AppConfig {

}
  • XML 설정으로 @AspectJ 지원 활성화 방법
<aop:aspectj-autoproxy/>

 

 

 

➤ Aspect 선언

 

@AspectJ 지원이 활성화

-> @AspectJ aspect(@Aspect 애너테이션이 있음)이 있는 클래스로 애플리케이션 컨텍스트에 정의된 모든 빈이 Spring에서 자동으로 감지

-> Spring AOP를 구성하는데 사용된다.

 

import org.aspectj.lang.annotation.Aspect;

@Aspect
public class AspectExample {

}

 

 

 

➤ Pointcut 선언

  • pointcut 선언은 이름과 매개변수를 포함하는 Signature와 메서드 실행을 정확히 결정하는 pointcut 표현식의 두 부분으로 구성된다.
  • pointcut 표현식은 @Pointcut 애너테이션 사용

 

 

 

 

읽어주셔서 감사합니다. 좋은하루 되세요 😉

오개념 지적은 환영입니다

 

 

 

 

 

 

 

❑ 관점 지향 프로그래밍(Aspect-Oriented Programming, AOP)

 

 

AOP(관점 지향 프로그래밍)가 OOP(객체 지향 프로그래밍)을 대체? ❎

횡단 관심사(부가 관심사)를 깔끔하게 처리하기 위해 OOP의 부족한 부분을 보조하는 목적으로 생겨난 것이다.

 

부가 관심사

 

 

 

❑ AOP가 필요한 이유

 

 

➤ AOP 기본 개념

 

핵심 기능(Core Concerns) : 업무 로직을 포함하는 기능

부가 기능(CROSS-CUTTING CONCERNS) : 핵심 기능을 도와주는 부가적인 기능 (로깅, 보안, 트랜잭션 등)

Aspect : 부가 기능을 정의한 코드인 Advice와 Advice를 어디에 적용할지 결정하는 포인트컷(PointCut)을 합친 개념 (Advice + PointCut -> Aspect)

 

 

 

➤ 객체 지향 프로그래밍(OOP)

 

  • 공통된 목적을 띈 데이터와 동작을 묶어 하나의 객체로 정의
  • 객체를 적극적으로 활용하여 기능을 재사용할 수 있는 것이 큰 장점
  • 객체를 잘 활용하기 위해선 관심사 분리(Separation of Concerns, SoC)의 디자인 원칙을 준수해야함

 

 

 

➤ OOP의 한계

 

  • 비즈니스 코드에 트랜잭션, 보안, 로깅 등의 코드가 존재하게 된다.
  • 위의 기능은 업무와는 관련없지만 필수적인 부가 기능이라서 빠질 수 없다.
  • 부가 기능은 불특정 다수 클래스에 존재하게 된다.
  • 비즈니스 클래스에 횡단 관심사와 핵심 관심사가 공존하게 된다.
  • 메소드 복잡도 증가 -> 비즈니스 핵심 로직 코드 파악하기 어려움
  • 부가 기능의 불특정 다수 메소드 반복적으로 구현 -> 횡단 관심사의 모듈화가 어려움

 

관심사의 분리는 모듈화의 핵심이다.

OOP만으로는 횡단 관심사 코드를 깔끔하게 분리하고 비즈니스 코드에 적용하기 어려웠다.

이러한 문제를 해결하기 위해 AOP가 등장했다.

 

 

 

➤ AOP의 핵심 기능과 부가 기능

 

 

▶️ 핵심 기능(Core Concerns)

객체가 제공하는 고유의 기능(업무 로직 등)

 

 

▶️ 부가 기능(CROSS-CUTTING CONCERNS)

핵심 기능을 보조하기 위해 제공되는 기능

로그 추적 로직, 보안, 트랜잭션 기능 등

단독으로 사용되지 않고 핵심 기능과 함께 사용됨

 

 ⬇️ 핵심 기능과 부가 기능 모델

핵심 기능과 부가 기능

 

특징

  • 핵심 기능인 XX로직과 부가 기능인 로그 추적 로직이 하나의 객체에 들어간다.
  • 부가 기능이 필요한 경우엔 위와 같이 합쳐져서 하나의 로직을 완성하게 된다.
  • 서비스를 실행하면 핵심 기능과 부가 기능이 함께 실행된다.

 

 

 

➤ 공통으로 사용하는 부가 기능

 

부가 기능은 보통 여러 클래스에서 함께 사용한다.

이러한 부가 기능은 횡단 관심사가 된다.

부가 기능을 여러 곳에 적용하려면 중복 코드가 생기게 되고 그렇게 되면 수정할 때 각각의 클래스를 찾아가면서 수정해야 한다.

 

 

➤ AOP가 필요한 이유

 

소프트웨어에서 변경지점은 하나가 될 수 있도록 잘 모듈화가 되어야 한다.

부가 기능을 애플리케이션 전반에 적용하는 문제는 OOP 방식으로는 해결이 어렵기 때문에 AOP가 필요하다.

 

 

 

 

❑ AOP 기본 용어 정리

 

 

 

AOP 기본 용어

 

 

 

➤ Aspect(애스팩트)

 

여러 객체에 공통으로 적용되는 기능

Advice + Pointcut 을 모듈화하여 애플리케이션에 포함되는 횡단 기능

여러 어드바이스와 포인트컷이 함께 존재함

 

 

 

➤ Join Point (조인 포인트)

 

  • AOP를 적용할 수 있는 모든 지점을 나타내는 추상적인 개념이다.
  • 클래스 초기화, 객체 인스턴스화, 메서드 호출, 필드 접근, 예외 발생과 같은 애플리케이션 실행 흐름에서의 특정 포인트를 의미한다.
  • 애플리케이션에 새로운 동작을 추가하기 위해 조인포인트에 관심 코드(aspect code)를 추가할 수 있다.
  • 횡단 관심은 조인포인트 전/후에 AOP에 의해 자동으로 추가된다.
  • 스프링 AOP는 프록시 방식을 사용하므로 조인 포인트는 항상 메서드 실행 지점으로 제한된다.

 

 

 

➤ Advice(어드바이스)

 

  • join point에서 수행되는 코드를 의미한다.
  • Aspect를 언제 핵심 코드에 적용할 지를 정의한다.
  • 시스템 전체 aspect에 API 호출을 제공한다.
  • 부가 기능에 해당된다.

 

 

 

➤ Pointcut(포인트컷)

 

  • 조인포인트 중에서 어드바이스가 적용될 위치를 선별하는 기능이다.
  • AspectJ 표현식을 사용해서 지정한다.
  • 프록시를 사용하는 스프링 AOP는 메서드 실행 지점만 포인트컷으로 선별 가능하다.

 

 

 

➤ Weaving(위빙)

 

  • pointcut으로 결정한 target의 joinpoint에 advice를 적용하는 것이다. -> advice를 핵심코드에 적용하는 것
  • 핵심 기능 코드에 영향을 주지 않고 부가 기능을 추가할 수 있다.
  • AOP 적용을 위해 aspect 객체에 연결한 상태이다.

 

 

 

➤ AOP 프록시(proxy)

 

  • AOP 기능을 구현하기 위해 만든 프록시 객체이다.
  • 스프링에서 AOP 프록시는 JDK 동적 프록시나 CGLIB 프록시 중 하나이다.

※ 프록시에 대한 자세한 내용은 글 하단부에 작성했다.

 

 

➤ Target(타겟)

 

  • 핵심 기능을 담고 있는 모듈
  • 부가 기능을 적용할 대상
  • Advice 받는 객체, 포인트컷으로 결정

 

 

➤ Advisor(어드바이저)

 

하나의 어드바이스와 하나의 포인트 컷으로 구성된다.

 

 

 

 

❑ 추가 학습

 

 

➤ Spring Proxy(프록시)

 

Spring AOP는 프록시 기반이다.

Spring에서 사용하는 프록시는 JDK dynamic 프록시와 CGLIB 프록시로 두가지다.

메서드를 직접 부르지 않고 프록시를 통해서 메서드를 불러온다.

프록시는 대리자 역할을 한다고 볼 수 있다.

 

 

▶️ JDK Dynamic proxy vs. CGLIB proxy

 

※ JDK Dynamic proxy (JDK 동적 프록시)

  • JDK와 함께 사용할 수 있다.
  • Reflaction을 통해 동적으로 프록시 객체 생성
  • 해당 타겟에 의해 구현된 모든 인터페이스가 프록시 된다.
  • 인터페이스를 구현하는 경우 스프링은 자동으로 JDK 동적 프록시를 사용한다.

 

 

※ CGLIB

  • 스프링이 프록시를 만들기 위해 사용하는 third party library 이다.
  • 클래스 상속을 통해 프록시 객체 생성
  • 구현한 인터페이스가 없을 때 사용한다.

 

 

참고) 프록시 공식 레퍼런스

https://docs.spring.io/spring-framework/docs/3.0.0.M3/reference/html/ch08s06.html

 

8.6 Proxying mechanisms

Spring AOP uses either JDK dynamic proxies or CGLIB to create the proxy for a given target object. (JDK dynamic proxies are preferred whenever you have a choice). If the target object to be proxied implements at least one interface then a JDK dynamic proxy

docs.spring.io

 

 

 

➤ Spring AOP와 AspectJ

 

 

▶️ Spring AOP

  • 목적 : Spring IoC를 통한 간단한 AOP 구현 -> 완전한 AOP를 의도한 것이 아님
  • Spring Container에 의해 관리되는 bean에만 적용 가능

 

 

▶️ AspectJ

  • 목적 : 완전한 AOP를 제공하는것
  • Spring보다 강력하지만 복잡하다
  • 모든 객체에 적용이 가능하다

 

 

참고) Bealdung 자료 번역 글

https://logical-code.tistory.com/118

 

Spring AOP와 AspectJ 비교하기

Thanks to @ㅅㅈㅎ 님 덕분에 3-5 첫번째 문장의 오타를 수정했습니다. 감사합니다! (더 간편합니다다. ⇢ 더 간편합니다.) @김성수 님 덕분에 3-2. Weaving의 오타를 수정했습니다. 감사합니다! (컴파일

logical-code.tistory.com

 

 

 

 

읽어주셔서 감사합니다.

오개념에 대한 지적은 언제나 환영입니다. 

 

 

 

 

프로그램을 짤 때 좋은 코드인지 볼 수 있는 척도 중 하나

느슨한 결합도 높은 응집도

 

오늘은 어제 다 못한 스프링 트라이앵글을 마저 학습했다.

오늘 학습한건 AOP와 PSA이다.

Spring 삼각형

 

 

❑ AOP(Aspect Oriented Programming)

 

 

➤ AOP란?

 

번역하면 관심지향 프로그래밍

객체 지향은 알겠는데 관심지향 프로그래밍에서 관심은 무엇을 의미할까?

 

고양이를 키우는 집사들은 다 다른 방식으로 키운다.

어떤 집사는 고양이에게 좋은 음수대를 사주고 또 어떤 집사는 비싼 캣타워를 사준다.

이렇게 집사들의 고양이 키우는 방식은 다 다르지만 모두 공통적으로 고양이의 행복을 바란다.

집사들이 고양이의 행복이라는 공통 관심사를 가지고 있는 것처럼 AOP에서 'Aspect'는 애플리케이션에 필요한 기능 중에서 공통적으로 적용되는 기능에 대한 관심이다.

 

 

➤ 공통 관심사항과 핵심 관심사항

 

AOP에서 관심사항에는 공통 관심사항핵심 관심사항이 있다.

공통 관심사항 : 애플리케이션 전반에 걸쳐 공통적으로 사용하는 기능들에 대한 관심사

핵심 관심사항 : 비즈니스 로직, 애플리케이션의 주 목적을 달성하기 위한 핵심 로직에 대한 관심사

핵심 관심사항과 반대되는 의미에서 공통 관심사항을 부가 관심사항이라고 부르기도 한다.

 

예를 들어서 음식을 주문하는 애플리케이션을 만든다고 했을 때

핵심 기능에는 음식 선택, 계산, 주문 취소가 들어갈 수 있고

공통적으로 들어가는 기능에는 로깅, 보안, 트랜잭션이 있다.

관심사 예시

 

공통 관심사와 핵심 관심사를 그림으로 그려보면 위와 같이 그려진다.

핵심기능과 부가기능은 떨어져 있고 부가기능들이 핵심기능을 관통한다.

결론적으로 AOP는 애플리케이션을 만들 때 핵심기능 로직에서 공통기능 로직을 분리해서 따로 작성하는 것이다.

 

 

 

➤ 왜 AOP가 필요할까?

 

핵심 로직과 공통 로직을 분리하면 다음과 같은 장점이 있다.

  • 코드가 간결해진다
  • 객체 지향적으로 설계할 수 있다
  • 코드를 재사용하기 쉽다

 

 

※ AOP의 예시로 학습자료에 있던 JDBC 트랜잭션에서 중요한 부분을 정리해보았다.

트랜잭션(Transaction) : 데이터를 처리하는 하나의 작업 단위

같은 트랜잭션 내에 있는 기능 중 하나라도 오류를 발생하면 모든 작업은 취소된다. (All or Nothing)

모든 작업이 정상적으로 수행되어야만 정상적으로 반영한다. (commit)

하나의 작업이라도 실패하면 모든 작업을 롤백(rollback) 시킨다.

 

 

 

 

❑ PSA(Portable Service Abstraction)

 

 

➤ 추상화(Abstraction)의 개념

 

어떤 클래스의 본질적인 특성만을 추출해서 일반화 하는것을 추상화라고 한다.

설계의 관점에서는 추상화보다 일반화가 적절한 용어이다.

자바에서 추상화의 대표적인 방법이 인터페이스(Interface) 이다.

 

클라이언트가 추상화된 상위 클래스를 일관적으로 바라보며 하위 클래스들의 기능을 사용하는 것이 일관된 서비스 추상화(PSA)이다.

여기서 클라이언트의 영역에 대해서 조금 생각해보자.

서버/클라이언트에서 클라이언트는 서버측의 기능을 이용하는 입장이다.

대표적인 클라이언트는 웹 브라우저이다.

하지만 코드 레벨에서 어떤 클래스의 기능을 사용하는 측 역시 클라이언트라고 부른다.

 

 

➤ 서비스에 적용되는 일관된 서비스 추상화(PSA) 기법

 

예시로 java 콘솔 애플리케이션에서 클라이언트가 데이터베이스에 연결하기 위해서는 JdbcConnector라는 기능을 사용하려고 한다.

JdbcConnector는 애플리케이션에서 사용하는 서비스 중 하나라고 생각하면 된다.

데이터베이스에 연결하기 위한 JDBC 인터페이스의 구현체는 OracleJdbcConnector, MariaDBJdbcConnector, SQLiteJdbcConnector가 있다.

이때 클라이언트가 JDBC의 구현체에 바로 연결하는 것이 아닌 JdbcConnector 인터페이스를 통해 간접적으로 연결되어 느슨한 결합으로 연결되어 있다.

어떤 JdbcConnector를 이용해도 JDBC에 작성되어 있는 공통기능을 일관된 방식으로 사용할 수 있다.

기능이 작동하는 방식은 각각의 JDBC를 구현한 객체에 작성되어 있는데로 작동한다.

 

이처럼 애플리케이션에서 서비스의 기능을 접근하는 방식 자체를 일관되게 유지하면서 기술을 유연하게 사용할 수 있도록 하는 것을  PSA(일관된 서비스 추상화)라고 한다.

 

 

➤ PSA가 필요한 이유

 

어떤 서비스를 이용하기 위한 접근 방식을 일관된 방식으로 유지해서

애플리케이션에서 사용하는 기술이 변경되더라도 최소한의 변경만으로 변경된 요구사항을 반영하기 위해서이다.

 

PSA를 통해서 애플리케이션의 요구 사항 변경에 유연하게 대처할 수 있다.

 

Spring에서 PSA가 적용되는 분야로는 트랜잭션 서비스, 메일 서비스,  Spring Data 서비스 등이 있다.

 

 

 

 

 

읽어주셔서 감사합니다. 🥰 좋은하루 되시길 바랍니다.

오개념에 대한 지적은 늘 환영입니다. ^^

1