나의개발일지
Spring) AOP 본문
728x90
AOP ( Aspect Oriented Programming )
등장 배경
- 핵심 관심 사항(core concern)과 공통(부가) 관심 사항 (cross-cutting concern)
- 기존 OOP에서는 공통관심사항을 여러 모듈에서 적용하는데 있어 중복된 코드를 양상 하는 한계가 존재함
- 이를 해결하기 위해 AOP가 등장
- Aspect Oriented Programming은 문제를 해결하기 위한 핵심 관심 사항과 전체에 적용되는 공통 관심 사항을 기준으로 프로그래밍함으로써 공통 모듈을 손쉽게 적용할 수 있게 함
OOP란?
객체지향
객체 : 주체가 아닌 것, 주체가 활용하는 것 객체 지향 프로그래밍 : 주변의 많은 것들을 객체화 해서 프로그래밍 하는것 객체 지향 언어의 특징 OOP is A P.I.E Abstraction(추상화) Polymorphism(다형성) Inh
cacaodotori.tistory.com
개요
- AOP는 application에서의 관심사의 분리(기능의 분리) 즉, 핵심적인 기능에서 부가적인 기능을 분리한다
- 분리한 부가기능 어스펙트(Aspect)라는 독특한 모듈 형태로 만들어서 설계하고 개발하는 방법
- OOP를 적용하여도 핵심기능에서 부가기능을 쉽게 분리된 모듈로 작성하기 어려운 문제점을 AOP가 해결
- AOP는 부가기능을 어스펙트(Aspect)로 정의하여, 핵심기능에서 부가기능을 분리함으로써 핵심기능을 설계하고 구현할 때 객체지향적인 가치를 지킬 수 있도록 도화주는 개념
그림과 같이 기존 Application 에서는 핵심 관심사항과 공통 관심사항이 한 곳에 몰려있지만 AOP를 적용한 Application은핵심 관심사항과 공통 관심사항이 분리되어 효율적인 유지보수를 할 수 있게 되고 객체 지향적인 가치를 얻게 된다.
Spring AOP
AOP 용어
용어 | 설명 |
Target | 핵심기능을 담고 있는 모듈로 target은 부가기능을 부여할 대상이 됨. |
Advice | 어느 시점(Ex : method의 수행 전/후, 예외 발생 후 등..)에 어떤 공통 관심 기능(Aspect)을 적용할지 정의 한 것. Target에 제공할 부가기능을 담고 있는 모듈. |
JoinPoint | Aspect가 적용 될 수 있는 지점. (method, field) 즉, target 객체가 구현한 인터페이스의 모든 method는 JoinPoint가 됨. |
Pointcut | 공통 관심 사항이 적용될 JoinPoint Advice를 적용할 target의 method를 선별하는 정규 표현식. Pointcut 표현식은 execution으로 시작하고 method의 Signature를 비교하는 방법을 주로 이용 |
Aspect | 여러 객체에서 공통으로 적용되는 공통 관심 사항. (transaction, logging, security..) AOP의 기본 모듈. Aspect = Advice + Pointcut Aspect는 Singleton 형태의 객체로 존재 |
Advisor | Advisor = Advice + pointcut Advisor는 Spring AOP에서만 사용되는 특별한 용어 |
Weaving | 어떤 Advice를 어떤 Pointcut(핵심사항)에 적용시킬 것인지에 대한 설정(Advisor) 즉 Pointcut에 의해서 결정된 타겟의 JoinPoint에 부가기능(Advice)을 삽입하는 과정을 뜻함 Weaving은 AOP의 핵심기능(Target)의 코드에 영향을 주지 않으면서 필요한 부가기능(Advice)을 추가할 수 있도록 해주는 핵심적인 처리과정 |
Spring AOP 특징
Spring은 프록시(Proxy) 기반 AOP를 지원
- Spring은 Target 객체에 대한 Proxy를 만들어 제공
- Target을 감싸는 Proxy는 실행시간(Runtime)에 생성
- Proxy는 Advice를 Target 객체에 적용하면서 생성되는 객체
프록시(Proxy)가 호출을 가로챈다 (Intercept)
- Proxy는 Target 객체에 대한 호출을 가로챈 다음 Advice의 부가기능 로직을 수행하고 난 후에 Target의 핵심 기능 로직을 호출한다. (전처리 Advice)
- 또는 Target의 핵심 기능 로직 method를 호출한 후에 부가기능(Advice)을 수행하는 경우도 있다 (후처리 Advice)
Spring AOP는 method JoinPoint만 지원
- Spring은 동적 Proxy를 기반으로 AOP를 구현하므로 method JoinPoint만 지원한다.
- 즉, 핵심기능 (Target)의 method가 호출되는 런타임 시점에만 부가기능(Advice)를 적용할 수 있다.
- 반면 AspectJ 같은 고급 AOP framework를 사용하면 객체의 생성, 필드값의 조회와 조작, static method 호출 및 초기화 등의 다양한 작업에 부가기능을 적용할 수 있다.
자주쓰는 Point-Cut 표현식
Point-Cut | 선택된 Joinpoint |
execution(public * * (..)) | public 메소드 실행 |
execution(* set*(..)) | 이름이 set으로 시작하는 모든 메소드 실행 |
execution(* com.test.service.AccountService.*(..)) | AccountService 인터페이스의 모든 메소드 실행 |
execution(* com.test.service.*.*(..)) | service 패키지의 모든 메소드 실행 |
execution(*.com.test.service..*.*(..)) | service 패키지와 하위 패키지의 모든 메소드 실행 |
within(com.test.service.*) | service 패키지 내의 모든 결합점 |
within(com.test.service..*) | service 패키지 및 하위 패키지의 모든 결합점 |
AOP 구현
1. POJO Class를 이용한 AOP 구현
XML Schema를 이용한 AOP 설정
< aop namespace와 XML Schema 추가 >
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
aop namespace를 이용한 설정
<!-- AOP 설정 -->
<bean id="ptAdvice"
class="com.ssafy.aop.step01.around.PerformanceTraceAdvice" />
<!-- com.ssafy.board package안에 있는 Dao로 끝나는 모든 클래스의 모든 메소드에 적용 -->
<aop:config>
<aop:aspect id="traceAspect" ref="ptAdvice">
<aop:pointcut id="publicMethod"
expression="execution(public * com.ssafy.board..*Dao.*(..))" />
<aop:around method="trace" pointcut-ref="publicMethod" />
</aop:aspect>
</aop:config>
aop 설정 태그
aop:config aop설정의 root 태그 (weaving들의 묶음.)
aop:aspect Aspect 설정 (하나의 weaving에 대한 설정.)
aop:pointcut Pointcut 설정
Advice 설정 태그
aop:before method 실행 전 실행 될 Advice
aop:after-returning method가 정상 실행 후 실행 될 Advice
aop:after-throwing method에서 예외 발생시 실행 될 Advice. (catch block)
aop:after method가 정상 또는 예외 발생에 상관없이 실행 될 Advice (finally block)
aop:around 모든 시점(실행 전, 후) 에서 적용시킬 수 있는 Advice
설정파일 aop:aspect
- 한 개의 Aspect(공동 관심 기능)을 설정
- ref 속성을 통해 공통 기능을 가지고 있는 bean을 연결
- id는 이 태그의 식별자 설정
- 자식 태그로 aop:pointcut advice관련 태그가 올 수 있다.
설정 파일 aop:pointcut
- Pointcut(공통 기능이 적용될 곳)을 지정하는 태그
- aop:config나 aop:aspect의 자식 태그
- aop:config 전역적으로 사용
- aop:aspect 내부에서 사용
- AspectJ 표현식을 통해 pointcut 지정
- 속성
- id : 식별자로 advice 태그에서 사용됨
- expression : pointcut 지정
POJO 기반 Advice Class 작성
POJO 기반 Aspect Class 작성
- 설정 파일의 advice 관련 태그에 맞게 작성한다.
- <bean>으로 등록 하며 aop:aspect의 ref 속성으로 참조한다.
- 공통 기능 메소드 : advice 관련 태그들의 method 속성의 값이 method의 이름이 된다.
Advice 정의 관련 태그
- pointcut : 직접 pointcut을 설정, 호출 할 method의 패전 지정
- pointcut-ref : aop:pointcut 태그의 id명을 넣어 pointcout 지정
- method : Aspect bean에서 호출할 method명 지정
POJO 기반의 Class로 작성
- class명이나 method명에 대한 제한은 없다.
- method 구문은 호출되는 시점에 따라 달라 질 수 있다.
- method의 이름은 advice 태그 (aop:before) 에서 method 속성의 값이 method명이 된다.
2. Annotation을 이용한 AOP 구현
@aspect Annotation을 이용한 AOP 구현
- @Aspect Annotation을 이용하여 Aspect Class에 직접 Advice 및 Pointcut등을 설정
- 설정 파일에 <aop:aspectj-autoproxy/>를 반드시 추가
- Aspect Class를 <bean>으로 등록
- 어노테이션
- @Aspect, @Beform, @AffterReturning, @AfterThrowing, @After, @Around
- Around를 제외한 나머지 method들은 첫 argument로 JoinPoint를 가질 수 있다.
- Around method는 argument로 ProceedingJoinPoint를 가질 수 있다.
@Aspect
public class PerformanceTraceAdvice {
@Pointcut("execution(public * com.company.board..*Dao.*(..))")
public boid profileTarget() {
}
@Around("profileTarget()")
public Object trace(ProceedingJoinPoint joinPoint) throw Throwable {
String signature = joinPoint.getSignature().toShortString();
StopWatch stopWatch = new StopWatch();
stopWatch.start();
Object result = joinPoint.proceed();
stopWatch.stop();
System.out.println(signature + " 실행시간 : " + stopWatch.getTotalTimeMillis());
return result;
}
}
728x90
반응형
'Back-End > Spring' 카테고리의 다른 글
Spring) Mybatis (2) | 2024.04.23 |
---|---|
Spring) Interceptor (0) | 2024.04.19 |
Spring) DI 의존성 주입 (0) | 2024.04.15 |
Spring) IoC & Container (0) | 2024.04.15 |
Spring) SpringMVC (1) | 2024.01.04 |