반응형
Spring AOP 사용하기
1) aspectj 라이브러리 추가 필요
2) Advice가 동작할 수 있게하는 class 생성
: aspectJ의 autoProxy사용에 관한 설정을 해 주어야 advice가 동작
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass=true)
public class ContextConfiguration {
}
@Aspect
: 클래스 선언부에 @Aspect 어노테이션을 정의
해당 클래스를 Aspect로 사용하려면 Bean으로 등록해야 하므로 @Component 어노테이션도 함께 정의해야 함.
@Component
@Aspect
public class AroundLog {
@Before Advice
@Component
@Aspect
public class BeforeAttendingAdvice {
@Before("StudentPointcut.studyPointcut()")
public void beforeAttending(JoinPoint joinPoint) {
System.out.println("=============== Before Attending ==================");
System.out.println("오늘도 신나게 등원해서 입실 카드를 찍는다");
System.out.println("수강생 타입 : " + joinPoint.getTarget().getClass());
System.out.println("수강생의 행위 :" + joinPoint.getSignature());
System.out.println("행위 요약 : " + joinPoint.getSignature().getName());
System.out.println("수강생의 열정 :" + ((Passion)joinPoint.getArgs()[0]).getScore());
System.out.println("===================================================");
}
}
출력 결과
: study 메소드 호출 전에 실행되는걸 알수 있다.
@AfterAdvice Advice
@Aspect
@Component
public class AfterAttendingAdvice {
@After("execution(* com.greedy.section01.advice.annotation..*(..))")
public void afterAttending(JoinPoint joinPoint) {
System.out.println("=============== Arter Attending ==================");
System.out.println("내일도 학원에 가서 열공해야징~~~라는 마음으로 잠자리에 듣니다.");
System.out.println("수강생 타입 : " + joinPoint.getTarget().getClass());
System.out.println("수강생의 행위 :" + joinPoint.getSignature());
System.out.println("행위 요약 : " + joinPoint.getSignature().getName());
System.out.println("수강생의 열정 :" + ((Passion)joinPoint.getArgs()[0]).getScore());
System.out.println("===================================================");
}
}
출력 확인
@AfterReturning Advice
: returning 속성은 리턴 값으로 받아 올 오브젝트의 매개변수 이름과 동일해야 함.
JoinPoint는 방드시 첫 번째 매개변수로 선언!
@Aspect
@Component
public class AfterReturninggAttendingAdvice {
@AfterReturning(pointcut="execution(* com.greedy.section01.advice.annotation..*(..))", returning="result")
public void afterReturningAttending(JoinPoint joinPoint, Object result){
(returning 이름과 동일하게 작성, 순서는 JoinPoint 먼저 작성)
result에 대해 출력
System.out.println("============AfterReturning Attending ===================");
System.out.println("오늘의 이해도 : " + ((AchievementResult)result).getUnderstandingScore());
System.out.println("오늘의 만족도 : " + ((AchievementResult)result).getSatisfactionScore());
정상 수행 후 반환하는 반환 값을 원하는대로 가공해서 넘겨줄 수도 있음
취업률 수치를 백분율로 환산해서 퍼센트로 가공(1000점 만점)
double employeementRate = ((AchievementResult)result).getEmployeementRate();
double percent = employeementRate / 1000.0 * 100;
((AchievementResult)result).setEmployeementRate(percent);
}
}
출력 확인
@AfterThrowing Advice
@Aspect
@Component
public class AfterThrowingAttendingAdvice {
@AfterThrowing(pointcut="execution(* com.greedy.section01.advice.annotation..*(..))", throwing="exception")
public void afterThrowingAttending(JoinPoint joinPoint, Throwable exception) Throwable : 상위타입의 에러 / throwing="exception"값과 일치해야함
System.out.println("===================After Throwing Attending ======================");
System.out.println(exception.getMessage());
System.out.println("====================================================================");
}
}
출력확인
: Student class에 작성해 놓은 에러메세지 출력
@Around Advice
: 조인 포인트의 진행 호출을 잊는 경우가 발생할 수도 있어 주의가 필요. 남용x
@Aspect
@Component
public class AroundAttendingAdvice {
@Around("studentAroundPointcut()")
public Object aroundAttending(ProceedingJoinPoint joinPoint) throws Throwable {
system.out.println("================ Around Attending Before ====================");
System.out.println("오늘도 학원에 가서 열심히 공부해야지~~~라는 마음으로 아침 일찍 일어납니다.");
공부 시간 체크하기 위해 스탑워치 사용
StopWatch stopWatch = new StopWatch();
stopWatch.start();
joinPoint.proceed();를 사용하면 원본 조인 포인트를 반환할 수 있음
Object result = joinPoint.proceed();
ProceedingJoinPoint 객체에서도 JoinPoint 객체처럼 정보를 얻어올 수 있음
if(joinPoint.getTarget() instanceof GreedyStudent) {
System.out.println("수업이 끝나도 학원이 닫을 때까지는 끝난게 아닙니다. 자율적 스터디 그룹고 ㅏ함께 다시 공부합니다!~!");
}
스탑워치 종료
stopWatch.stop();
메소드의 수행 시간을 확인하는 용도
System.out.println("총 공부 소요 시간 : " + stopWatch.getTotalTimeMillis() + "(ms)");
System.out.println("===============================================================");
원본 조인 포인트를 호출한 쪽 혹은 다른 어드바이스가 다시 실행할 수 있도록 리턴 값을 이어서 반환
return result;
}
출력 확인
반응형
'프로그래밍 > Spring & Spring boot' 카테고리의 다른 글
[Spring/스프링] CGLib 방식으로 Proxy 구현하기 (0) | 2022.09.05 |
---|---|
[Spring/스프링] 리플렉션 Reflection (0) | 2022.09.05 |
14 Spring : @Pointcut 어노테이션 표현식 (0) | 2022.09.02 |
13 Spring : AOP 개념 정리 (0) | 2022.09.02 |
12 Spring : bean 초기화, 소멸 설정하기(init-method , ditory-method) (0) | 2022.09.02 |