# PountCut 표현식 문법
- AspectJ 포인트컷 표현식은 포인트컷 지시자를 이용하여 작성함
- 대표적으로 execution() 지시자를 사용해 표현
ex) execution(* hello(..))
hello라는 이름을 가진 메소드를 선정(..은 파라미터는 모든 종류를 허용)
ex) execution(* hello())
hello 메서드 중 파라미터가 없는 것만 허용
ex) execution( * myspring.user.service.UserServiceImpl.*(..))
myspring.user.service.UserServiceImpl 클래스를 직접 지정하여 해당 클래스의 모든 메서드 지정
ex) execution( * myspring.user.service.*.*(..))
myspring.user.service 패키지의 모든 클래스에 적용(서브패키지의 클래스는 미포함)
ex) execution(* myspring.user.service..*.*(..))
myspring.user.service 패키지와 서브패키지의 모든 클래스를 포함
ex) execution(* *..Target.*(..))
Target이라는 이름의 모든 클래스에 적용(다른 패키지에 같은 이름의 클래스가 있어도 적용이 된다는 점 유의)
# Spring AOP 구현 방식
1) XML 기반의 POJO 클래스 이용한 AOP 구현
- 부가기능을 제공하는 Advice 클래스 작성
- XML 설정 파일에 <aop:config>를 이용해서 Aspect를 설정(어드바이스와 포인트 컷을 설정)
2) @Aspect 어노테이션을 이용한 AOP 구현
- @Aspect 어노테이션을 이용해서 부가기능을 제공하는 Aspect 클래스를 작성
- Aspect 클래스는 어드바이스를 구현하는 메서드와 포인트컷을 포함
- XML 설정 파일에 <aop:aspectj-autoproxy />를 설정
# @Aspect 어노테이션
- Aspect 클래스를 선언할 때 사용
- AspectJ 5버전에 새로 추가됨
- XML 설정파일에 어드바이스와 포인트컷을 설정하는 것이 아니라 클래스 내부에 정의 가능
- <aop:aspectj-autoproxy /> 태그를 설정파일에 추가시 어노테이션이 적용된 Bean을 Aspect로 사용 가능
# Advice 종류와 정의를 위한 어노테이션
# JoinPoint 인터페이스
- AOP가 적용되는 지점
- 모든 어드바이스는 org.aspectj.lang.JoinPoint 타입의 파라미터를 어드바이스 메서드에 첫 번째 매개변수로 선언 가능
- Around 어드바이스는 JoinPoint의 하위 클래스인 ProceedingJoinPoint 타입의 파라미터를 필수적으로 선언해야 함
# 실습 - 메소드 수행시간 확인 Aspect 생성
- MeasuringAspect 생성
- @Around 디바이스 활용
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 {
@Around("execution(* kr.co.acomp.hello.service.*Service.*(..))")
public Object measuringMethodObject(
ProceedingJoinPoint joinPoint) throws Throwable{
long start = System.currentTimeMillis();
// Proceed 실제 타겟 메서드 실행
try {
return joinPoint.proceed();
} finally {
long result = System.currentTimeMillis() - start;
String targetMethodName = joinPoint.getSignature().getName(); // 메소드 이름 확인
System.out.println(targetMethodName + "running time is " + result); // log
}
}
}
서비스 수정
package kr.co.acomp.hello.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import kr.co.acomp.hello.dao.ArticleDAO;
import kr.co.acomp.hello.vo.Article;
@Service
public class BbsService {
...
public void testService() {
System.out.println("target invoked..");
}
}
컨트롤러 수정
package kr.co.acomp.hello.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import kr.co.acomp.hello.service.BbsService;
import kr.co.acomp.hello.vo.Article;
@Controller
@RequestMapping("/bbs")
public class BbsController {
@Autowired
private BbsService bbsService;
@RequestMapping("")
public String index() {
bbsService.testService();
return "home";
}
...
}
'Archived(Programming) > Spring #2(기초)' 카테고리의 다른 글
예외처리 (0) | 2020.03.18 |
---|---|
트랜잭션과 로깅 (0) | 2020.03.18 |
AOP(Aspect Oriented Programming) (0) | 2020.03.17 |
Dynamic SQL (0) | 2020.03.17 |
Mapper XML 파일 (1) | 2020.03.16 |