프로그래밍/Spring & Spring boot

15 Spring : @Aspect , @Before , @AfterAdvice, @AfterReturning, @AfterThrowing, @Around 사용하기

pupu91 2022. 9. 2. 19:34
반응형

 

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;
 }

 

 

출력 확인

반응형