=== 지극히 개인의 공부를 위함이며, 높은 확률로 적절치 않은 내용이 있을 수 있음을 미리 밝힙니다.
정정할 정보가 있거나 더 나은 정보가 있다면 댓글로 가르침을 요청드립니다. ===
[OOP]
OOP의 핵심은 공통된 목적을 띈 데이터와 동작을 묶어 하나의 클래스, 객체로 정의하는 것.
객체를 적극적으로 활용함으로써 기능을 재사용할 수 있는 것이 장점.
[문제점]
특정 객체에 핵심 기능과 부가 기능이 공존함.
1. 메소드 복잡도 증가 -> 비즈니스 코드 파악 어려움.
2. 부가 기능의 불특정 다수 메소드가 반복적으로 구현 -> 부가 기능의 모듈화가 어렵다.
[AOP]
애플리케이션의 로직을 핵심 기능 관점, 공통 기능 관점 으로 분리하여 그 관점을 기준으로 모듈화 하는 것
핵심 기능 관점
업무 로직을 포함한 애플리케이션의 주요 핵심 기능. (주문, 주문 변경, 결제)
공통 기능 관점
핵심 기능을 도와주는 부가적인 기능 (로깅, 보안, 트랜잭션)
단독으로 사용되지 않고, 핵심 기능과 함께 사용된다.
[AOP의 등장]
OOP 관점에서는 애플리케이션이 기능(동작)과 데이터를 묶어 클래스로 모듈화를 하여 구성되어 있는데
부가기능은 애플리케이션을 구성하고 있는 모든 클래스에서 사용되므로
결국 클래스간에 부가 기능이라는 중복 코드(횡단 관심사, CrossCutting Concerns)가 발생하게 되고,
이를 수정할 경우엔 해당 부가 기능을 사용하는 모든 클래스를 수정해야한다.
이와 같은 OOP 관점에서 발생하는 과도한 중복 코드, 수정의 번거로움을 해결하기 위해
AOP는 기능들의 관심사 분리를 통해 애플리케이션을 개선시키는데 목적이 있다.
Class A, Class B, Class C에서 각 색의 선들은 클래스에 나타나는 메소드 필드, 코드.
만약 Class A의 주황색 코드를 수정해야 한다면, Class B, Class C의 주황색 코드를 모두 수정해야 한다.
이는 SOLID 원칙 위배하며, 유지보수도 쉽지 않다.
이렇게 여러 클래스에 걸쳐 중복된 코드를 횡단 관심사 (CrossCutting Concerns)라고 한다.
횡단 관심사를 AOP에서는 Aspect라는 모듈화를 통해 해결한다.
*모듈화 : 공통된 로직이나 기능을 하나의 단위로 묶는 것.
개발자는 모듈화 시킨 Aspect를 사용하고자 하는 클래스에 정의만 해주면 된다.
즉, 중복되는 기능을 Aspect로 모듈화하고, 핵심적인 비즈니스 로직에서 분리하여 재사용 하겠다는 것이 AOP의 취지.
[AOP의 장점]
1. 애플리케이션 전체에 사용중인 공통 기능이 하나의 장소(Aspect)에서 관리된다.
2. 다른 서비스 모듈들이 본인의 목적에만 충실하고 그외 사항들은 신경쓰지 않아도 된다.
[AOP의 용어 및 개념]
1. [Join Point]
1. Advice가 적용될 수 있는 위치.
2. 애플리케이션을 실행할 때 특정 작업이 시작되는 시점
3. Spring AOP는 프록시 방식을 사용하므로, Join Point는 항상 메소드 실행 지점으로 제한된다.
=> Spring에서 조인포인트라고 하면 메소드 실행 지점을 가르키는 것.
4. Target(핵심기능) 객체가 구현한 인터페이스의 모든 메소드는 Join Point가 된다.
5. JoinPoint 메소드는 Advice의 종류에 따라 사용방법이 다소 다르지만,
기본적으로 Advice 메소드에 매개변수로 선언하면 된다.
2. [PointCut]
1. Join Point 중에서 Advice가 적용될 위치를 AspectJ 표현식을 사용해 선별하는 기능.
2. Advice(부가 기능)가 적용될 대상(Target/메서드)를 선정하는 방법.
3. Proxy를 사용하는 Spring AOP는 메서드 실행 지점만 포인트컷으로 선별 가능.
3. [Aspect]
1. 여러 객체에서 공통적으로 적용되는 기능.
2. Advice + PointCut
3. 핵심 기능에 부가되어 의미를 갖는 특별한 모듈. (위의 예제 참고)
4. AOP는 핵심적인 기능에서 부가적인 기능을 분리해서 Aspect라는 모듈을 만들어 설계하고 개발하는 방법.
4. [Target]
1. Advice(부가기능)을 부여할 대상.
2. 핵심 로직을 구현하는 클래스/메소드.
5. [Weaving]
1. 지정된 객체에 Aspect (Advice + PointCut)를 적용해서 새로운 Proxy 객체를 생성하는 과정.
Ex) A라는 객체에 Transaction Aspect가 지정되어 있다면,
A 객체가 실행되기 전, 커넥션을 오픈하고 실행이 끝나면 커넥션을 종료하는 기능이 추가된
Proxy객체 B가 생성되고, 이 B객체가 앞으로 A객체가 호출되는 시점에서 사용된다.
2. PointCut으로 결정한 Target의 JoinPoint에 Advice를 적용하는 것.
= Advice를 Target에 적용하는 것.
6. [AOP proxy]
1. AOP 기능을 구현하기 위해 만든 객체
2. Target(핵심 로직을 구현하는 클래스/메소드)을 감싸서 타겟의 요청을 대신 받아주는 Wrapping 오브젝트.
클라이언트에서 Target을 호출하면 Target대신 Target을 감싸는 Proxy가 호출되어,
Target 메소드 실행전에 선처리, Target 메소드 실행 후, 후처리를 실행시키도록 구성되어 있다.
3. Spring에서는 JDK 동적 프록시 (인터페이스), CGLIB 프록시 (추상 클래스)
AOP에서 Proxy는 호출을 가로챈 후, Advice에 등록된 기능을 수행 후 Target 메소드를 호출한다.
Ex) 예외 처리(Try Catch) 진행 시,
인터페이스A를 구현한 구현 객체B를 바로 사용하지 않고, 생성자로 구현객체B를 전달받는 Proxy 객체를
만들고 Proxy 객체에서 구현객체B에 있는 메소드 호출로 처리함.
7. [Advisor]
a Advice + a PointCut
8. [Advice] = 부가 기능, 횡단 관심사, 메서드 내에 부가 기능 코드
1. 부가 기능을 담은 구현체(메소드)
2. Aspect가 '무엇을', '언제' 하는지 의미한다.
[Advice 종류] : Target 메서드의 Aspect 실행 시점을 지정하는 애너테이션.
@Before
1. Target의 메서드가 실행되기 이전, 처리해야할 필요가 있는 부가 기능을 메소드 호출 전 실행.
2. 일반적으로 Return 타입이 void.
@After
Target 메서드의 결과에 관계없이 Target 메서드가 정상 실행되면 Advice 기능을 실행.
= Try Catch문의 Finally 와 같은 역할.
@AfterReturning
1. Target 메서드가 성공적으로 결과값을 반환 후에 Advice 수행.
2. returning 속성에 사용된 이름은 Advice 메소드의 매개변수와 이름이 일치해야한다.
3. returning 절에 지정된 타입의 값을 반환하는 메서드만 대상을 실행
@AfterThrowing
1. Target 메서드가 수행 중 예외를 던지면 Advice 기능 수행.
2. Throwing 속성에 사용된 이름은 Advice 메소드의 매개변수와 이름이 일치해야한다.
3. Throwing 절에 지정된 타입과 맞은 예외를 대상으로 실행한다.
@Around
1. Advice가 Target 메서드를 감싸서 Target 메서드 호출되기
전과 후 시점에 모두 처리해야 할 필요가 있는 Advice 기능.
=> JoinPoint 앞과 뒤에서 실행되는 Advice.
2. Target메소드 실행 전&후, 예외 발생 시점에 공통 기능을 실행
종류 | 설명 |
@Before Advice | 대상 객체의 메서드 호출 전에 Advice을 수행 |
@After Returning Advice | 대상 객체의 메서드가 예외 없이 실행된 이후 Advice 실행 |
@After Throwing Advice | 대상 객체의 메서드를 실행하는 도중 예외가 발생한 경우 Advice 실행 |
@After Advice | 종료 후 무조건 Advice 실행. (Try-Catch문 Finally 역할) |
@Around Advice | 대상 객체의 메서드 실행 전, 후, 예외 발생 시점에 Advice를 실행하는데 사용. |
[PointCut 표현식]
JoinPoint에서 Advice를 적용할 Target의 메소드를 선별하는 정규 표현식,
Advice가 실행되는 시기를 제어할 수 있다.
[PointCut 지시자 종류]
종류 | 설명 |
execution | 메서드 실행 JoinPoint를 매칭. |
within | 특정 타입 내의 Join Point를 매칭 |
args | 인자가 주어진 타입의 인스턴스인 Join Point |
this | 스피링 Bean 객체를 대상으로 하는 Join Point |
target | Target 객체를 대상으로 하는 Join Point. |
@whithin | 주어진 애너테이션이 있는 타입 내 JoinPoint |
@target | 실행 객체의 클래스 주어진 타입의 애너테이션이 있는 Join Point |
@annotation | 메서드가 주니어 애너테이션을 가지고 있는 조인 포인트 매칭 |
@args | 전달된 실제 인수의 런타임 타입이 주어진 타입의 애너테이션을 갖는 Join Point |
bean | Spring 전용 포인트컷 지시자이고, 빈의 이름을 포인트컷 |
[일반적인 PointCut 표현식들]
1. 모든 공개 메서드 발행
execution(public * * (..))
2. set 다음 이름으로 시작하는 모든 메서드 실행
execution(* set*(..))
3. AccountService 인터페이스에 의해 정의된 모든 메서드의 실행
execution(* com.xyz.service.*.*(..))
4. service 패키지에 정의된 메서드 실행
execution(* com.xyz.service.*.*(..))
5. 서비스 패키지 또는 해당 하위 패키지 중 하나에 정의된 메서드 실행
execution(* com.xyz.service..*.*(..))
6. 서비스 패키지 내의 모든 Join Point (Spring AOP에서만 메소드 실행)
within(com.xyz.service.*)
7. 서비스 패키지 또는 하위 패키지 중 하나 내의 모든 조인 포인트 (Spring AOP에서만 메서드 실행)
within(com.xyz.service..*)
8. AccountService 프록시가 인터페이스를 구현하는 모든 조인 포인트(Spring AOP에서만 메서드 실행)
this(com.xyz.service.AccountService)
9. AccountService 대상 객체가 인터페이스를 구현하는 모든 조인 포인트(Spring AOP에서만 메서드 실행)
target(com.xyz.service.AccountService)
10. 단일 매개변수를 사용하고 런타임에 전달된 인수가 Serializable과 같은 모든 조인 포인트.
args(java.io.Serializable)
11. 대상 객체에 @Transactional 애너테이션이 있는 모든 조인 포인트 (Spring AOP에서만 메서드 실행)
@target(org.springframework.transaction.annotation.Transactional)
12. 실행 메서드에 @Transactional 애너테이션이 있는 조인 포인트 (Spring AOP에서만 메서드 실행)
@annotation(org.springframework.transaction.annotation.Transactional)
13. 단일 매개 변수를 사용하고 전달된 인수의 런타임 유형이 @Classified 애너테이션을 갖는 조인 포인트
@args(com.xyz.security.Classified)
14. tradeService 라는 이름을 가진 Spring Bean의 모든 조인 포인트
bean(tradeService)
15. 와일드 표현식 *Service라는 이름을 가진 Spring Bean의 모든 조인 포인트
bean(*Service)
[JoinPoint] = AOP 적용 위치
조인포인트는 추상적인 개념이고, AOP를 적용할 수 있는 지점을 의미.
[JoinPoint 인터페이스 주요 기능]
1. JoinPoint.getArgs() : JoinPoint에 전달된 인자를 배열로 반환.
2. JoinPoint.getThis() : AOP 프록시 객체를 반환
3. JoinPoint.getTarget() : AOP가 적용된 대상 객체를 반환.
클라이언트가 호출한 비즈니스 메소드를 포함하는 비즈니스 객체를 반환.
4. JoinPoint.getSignature() : 조인되는 메소드에 대한 설명을 반환.
클라이언트가 호출한 메소드의 시그니처(리턴타입, 이름, 매개변수) 정보가 저장된 Signature 객체 반환
Signature : 객체가 선언하는 모든 연산은 연산의 이름, 매개변수로 받아들이는 객체들을 시그니처.
Signature가 제공하는 메소드
String getName() : 클라이언트가 호출한 메서드의 이름을 반환
String toLongString() : 클라이언트가 호출한 메서드의 리턴타입, 이름,
매개변수를 패키지 경로까지 포함해서 반환
String toShortString() : 클라이언트가 호출한 메소드 시그니처를 축약한 문자열로 반환
5. JoinPoint.toString() : 조인되는 방법에 대한 유용한 설명을 인쇄
[ProceedingJoinPoint 인터페이스의 주요 기능]
proceed() : 다음 Advice나 Target을 호출.
[AOP 애너테이션]
@Aspect // 클래스 레벨 애너테이션.
해당 클래스가 횡단관심사(부가기능)Class 임을 알려주는 Annotation.
자동으로 Bean으로 등록되는 것이 아니므로, 따로 Bean으로 등록하는 작업이 필요.
ex) @Component 처리
@Around ( PointCut 표현식 )
Advice의 한 종류로, 핵심 관심사(Target 메소드)의 실패 여부와 상관없이 전 후 로 실행되는 Advice.
@AspectJ
[애너테이션을 이용한 AOP]
@AspectJ 지원
@AspectJ는 애너테이션이 있는 일반 Java 클래스로 관점을 선언하는 스타일.
[@AspectJ 지원 활성화]
Spring 설정에서 @AspectJ aspect를 사용하기 위해서는 @AspectJ aspect에 기반한
Spring AOP설정과 이러한 aspect에 의해 조언되는 자동 프록시 Bean에 대한 Spring 지원을 활성화해야한다.
1. [Java설정으로 @AspectJ 지원 활성화 방법.]
@Configuration 으로 @AspectJ 지원을 활성화하려면 @EnableAspectJAutoProxy 애너테이션을 추가한다.
@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
}
2. [XML 설정으로 @AspectJ 지원 활성화 방법.]
XML 기반 구성으로 @AspectJ 지원을 활성화 하려면 aop:aspectj-autoproxy 요소를 사용한다.
<aop:aspectj-autoproxy/>
Aspect 선언
@AspectJ 지원이 활성화되면 @AspectJ 관점(@Aspect 애너테이션이 있음)이 있는 클래스로
ApplicationContext에 정의된 모든 Bean이 Spring에서 자동으로 감지되고, Spring AOP를 구성하는데 사용.
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class NotVeryUsefulAspect {
}
PointCut 선언
포인트컷 선언은 Advice가 적용될 JoinPoint를 결정하므로, Advice가 실행되는 시기를 제어할 수 있다.
Spring AOP는 Spring Bean에 대한 메서드 실행 조인 포인트만 지원하므로,
PointCut은 Spring Bean의 메소드 실행과 일치하는 것으로 생각할 수 있다.
포인트컷 선언은 이름과 매개변수를 포함하는 Signature와
우리가 관심 있는 메소드 실행을 정확히 결정하는 포인트컷 표현식의 두 부분으로 구성된다.
포인트컷 표현식은 @Pointcut 애너테이션을 사용하여 표시된다.
Advice 선언
어드바이스는 포인트컷 표현식과 연관되며, 포인트컷과 일치하는 메서드 실행 전후 또는 전후에 실행
포인트컷 표현식은 명명된 포인트컷에 대한 단순 참조이거나 제자리에 선언된 포인트컷 표현식일 수 있다.
Advice 선언
Advice는 PointCut 표현식과 연관되며, PointCut과 일치하는 일치하는 메서드 실행 전, 후 또는 전후에 실행.
'백엔드 학습 과정 > Section 2 [재귀함수, 자료구조, 네트워크]' 카테고리의 다른 글
코드스테이츠 백엔드스쿨 42기 Section2 회고록 (0) | 2022.12.17 |
---|---|
#7-1 Spring Framework 심화 [ Spring Container, Bean, BeanDefinition, Scope, Annotation ] (0) | 2022.12.15 |
#7. Spring Framework [기초] (0) | 2022.12.11 |
Spring IoC / DI 에 관한 학습. // 추가 업뎃 예정 (1) | 2022.12.10 |
#6-3. SQL 자가 학습 확인 문제들 (0) | 2022.12.08 |