코딩하는 문과생
[Spring] Spring 프레임워크(9) - AOP 본문
[AOP: Aspect Oriented Programming]
: 관심사의 분리(기능의 분리) - 핵심적인 기능에서 부가적인 기능(Aspect)을 분리
- 핵심기능(Core Concerns): 업무 로직
- 부가기능(Cross-cutting Concerns): 로깅, 보안
1. 런타임시 핵심기능과 부가기능이 결합되어 작동
2. Advice(부가기능 "자체") + PointCut(어디에 적용할 지에 대한 "문법") = Aspect = Advisor(Spring AOP)
3. Target = Core Concerns
4. JoinPoint: 어디에 "위치"해야할 지
5. 위빙(Weaving): 포인트컷에 의해서 결정된 타깃의 JoinPoint에 부가기능이 삽입되는 과정
- Spring AOP
- Spring은 프록시 기반 AOP를 지원
- 프록시가 호출을 가로챈다.
- Spring AOP는 메서드 조인 포인트만 지원한다.
ex. AOP
- pom.xml에 의존성 추가
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.10</version>
</dependency>
- root-context.xml에 프록시 기반 aop추가
<!-- AOP가 컨트롤러에는 적용되지 않는다. -->
<aop:aspectj-autoproxy/>
- SampleAspect작성
package kr.co.acomp.hello.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class SampleAspect {
//hello패키지내 모든 메소드
@Before("execution(* kr.co.acomp.hello..*.*(..))")
public void before(JoinPoint joinPoint) {
String targetMethodName = joinPoint.getSignature().getName();
System.out.println(targetMethodName+" is invoked...");
}
}
[PointCut표현식과 Advisor 구현]
- AspectJ 포인트컷 표현식을 따른다
ex. "execution(* aspects.trace.demo.*.*(..))"
(..): 모든 종류의 파라미터 허용
(): 파라미터가 없는 메소드에만 적용하겠다.
- Spring AOP의 구현 방식
XML POJO 클래스를 이용
- 트랜잭션 처리와 같이 구현되어 있는 부분을 사용할 경우
- <aop:config>
@Aspect 어노테이션을 이용
- 직접 부가기능을 구현할 경우
- <aop:aspectj-autoproxy/>태그를 설정파일에 추가하면 @Aspect 어노테이션이 적용된 Bean을 Aspect로 사용 가능
-Advice의 종류
- Around 어드바이스: JoinPoint가 앞과 뒤에서 실행되는 Advice - @Around("pointcut문법")
- Before 어드바이스 - @Before("pointcut문법")
- After Returning 어드바이스: JoinPoint 메서드 호출이 정상적으로 종료된 뒤에 실행되는 Advice - @AfterReturning("pointcut문법")
-JoinPoint 인터페이스
ex. getSignature(): 타겟 메서드의 정보 확인 가능
- ProceedingJoinPoint 인터페이스
JointPoint 인터페이스를 상속받는다.
Around 어드바이스와 사용된다.
ex. proceed(): 타겟 메서드를 실행시키는 메서드, 가령 타겟 메서드의 실행시간을 체크하는 기능을 예로 들 수 있다.
ex. 메소드 수행시간 확인 Aspect 생성
- MeasuringAspect 생성
package kr.co.acomp.hello.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class MeasuringAspect {
//서비스 메소드에만 적용해보자
//Aspect = Advice + PointCut
@Around("execution(* kr.co.acomp.hello.service.*Service.*(..))")
public Object measuringMethodRunningTime(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
try {
return joinPoint.proceed();
//타겟 메서드를 실행시키는 함수
}finally {
//타겟 메서드를 실행시킨 이후 내용
long result = System.currentTimeMillis() - start;
String targetMethodName = joinPoint.getSignature().getName();
System.out.println(targetMethodName + " running time is " + result);
}
}
}
- BbsService 추가
public void testService() {
System.out.println("target invoked..");
}
- BbsController 추가
@GetMapping("")
public String index() {
bbsService.testService();
return "index";
}
'웹 프로그래밍 > Spring' 카테고리의 다른 글
[Spring] Spring 프레임워크(11) - 예외처리 (0) | 2020.03.12 |
---|---|
[Spring] Spring 프레임워크(10) - 트랜잭션과 로깅 (0) | 2020.03.12 |
[Spring] Spring 프레임워크(8) - MyBatis (0) | 2020.03.10 |
[Spring] Spring 프레임워크(7) - Context분리와 전략 (0) | 2020.03.10 |
[Spring] Spring 프레임워크(6) - 데이터 접근 기술 (0) | 2020.03.09 |