본문 바로가기

프레임워크/Spring

[프레임워크] <Spring>〈Maven〉Advice의 @어노테이션화

추가 xml 설정

 <aop:aspectj-autoproxy/>

LogAdvice

@어노테이션

 Aspect

    반복적으로 발생하는 관심사를 분리하여 모듈화한다.

 

 Before

    지정된 포인트컷(Pointcut)이 실행되기 전에 실행되는 어드바이스를 정의한다.

코드

@Service 
@Aspect
public class LogAdvice {
	
	@Before("PointcutCommon.aPointcut()")
	public void printLog(JoinPoint jp) {
		
		String methodName=jp.getSignature().getName();
		
		System.out.println("BEFORE 어드바이스 : "+methodName);
		
		Object[] args=jp.getArgs();
		
		System.out.println("비즈니스 메서드에서 사용하는 인자 : "+args[0]);
		
		for(Object arg:args) {
			
			System.out.println(arg);
			
		}
		
		System.out.println("     비즈니스 메서드 수행 전에 로그를 출력합니다.");
		
	}

}

설명

 @Aspect을 통해 Aspect로 동작함을 나타낸다.

@Before을 사용하여 PointcutCommon.aPointcut()이라는 포인트컷에 해당하는 메서드가 호출되기 전에 실행될 메서드를 정의 한다.

해당 메서드는 printLog로 명명되었고, JoinPoint 객체를 매개변수로 받는다.

객체를 사용하여 호출되는 메서드에 대한 정보를 얻을 수 있다.

메서드 내에서는 호출되는 메서드의 이름과 인자들을 가져와서 출력한다.


AfterReturningAdvice

@어노테이션

Aspect

    반복적으로 발생하는 관심사를 분리하여 모듈화한다.

AfterReturning

   메서드가 반환값을 리턴한 후에 실행되는 어드바이스를 정의할 때 사용된다.

  ⇨ 메서드가 성공적으로 실행되었는지 확인하고 로그를 남길 때 사용될 수 있다.

   반환값을 가지고 추가적인 계산을 수행하는 등의 작업을 수행할 때 사용될 수 있다.

코드

@Service
@Aspect
public class AfterReturningAdvice {

	@AfterReturning(pointcut="PointcutCommon.bPointcut()", returning="returnObj")
	public void afterReturningPrintLog(JoinPoint jp, Object returnObj) {
		
		String methodName=jp.getSignature().getName();
		
		System.out.println("     AfterReturning 어드바이스 : "+methodName);

		Object[] args=jp.getArgs();
		
        // 인자가 DTO 1개일 확률이 높기때문
		System.out.println("     비즈니스 메서드에서 사용하는 인자 : "+args[0]); 
		
		for(Object arg:args) {
			
			System.out.println(arg);
			
		}

		System.out.println("     비즈니스 메서드의 OUTPUT : "+returnObj);
		
		if(returnObj instanceof MemberDTO) {
			
			MemberDTO mDTO=(MemberDTO)returnObj;
			
			if(mDTO!=null) {
				
				if(mDTO.getRole().equals("ADMIN")) {
					
					System.out.println("[관리자 로그인]");
					
					System.out.println(mDTO.getName()+"님 입장");
					
				}else {
					
					System.out.println("[사용자 로그인]");
					
				}
				
			}
			
		}
		
		System.out.println("     비즈니스 메서드 수행 후에 로그를 출력합니다.");
		
	}
	// 바인드 변수
    
}

설명

@Aspect을 통해 Aspect로 동작함을 나타낸다.

PointcutCommon.bPointcut()이라는 포인트컷에 해당하는 메서드가 실행된 후에 실행된다.

@AfterReturning 이 어드바이스가 해당 지점 이후에 실행되어야 함을 나타낸다.

afterReturningPrintLogJoinPoint와 호출된 메서드의 반환값을 매개변수로 받는다.

JoinPoint 객체는 Advice가 적용되는 지점에 대한 정보를 제공하고, 반환 값은 호출된 메서드의 반환값을 나타낸다.


AfterThrowingAdvice

@어노테이션

 Aspect

    반복적으로 발생하는 관심사를 분리하여 모듈화한다.

AfterThrowing

   메서드 실행 중 예외가 발생한 후에 실행되는 어드바이스를 정의할 때 사용된다.

  ⇨ 예외가 발생한 후에 추가적인 로직을 수행하거나 예외를 처리하는 등의 작업을 수행할 때 유용하게 활용된다.

코드

@Service
@Aspect
public class AfterThrowingAdvice {
	
	@AfterThrowing(pointcut="PointcutCommon.aPointcut()", throwing="exceptObj")
	
	public void printException(JoinPoint jp, Object exceptObj) {
		
		String methodName=jp.getSignature().getName();
		
		System.out.println("     AfterThrowing 어드바이스 : "+methodName);
		
		Object[] args=jp.getArgs();
		
		System.out.println("     비즈니스 메서드에서 사용하는 인자 : "+args[0]); // 인자가 DTO 1개일 확률이 높기때문
		
		for(Object arg:args) {
			
			System.out.println(arg);
			
		}

		if(exceptObj instanceof NumberFormatException) {
			
			System.out.println("값이 숫자가 아닙니다.");
			
		}else if(exceptObj instanceof ArithmeticException) {
			
			System.out.println("수학적인 오류입니다.");
			
			System.out.println("일부러 발생시킨 에러입니다.");
			
		}else {
			
			System.out.println("미확인 에러입니다.");
			
		}

		System.out.println("     비즈니스 메서드 수행에 예외가 발생했습니다.");
		
	}
	
}

설명

◎ @Aspect을 통해 Aspect로 동작함을 나타낸다.

PointcutCommon.aPointcut()이라는 포인트컷에 해당하는 메서드가 예외를 발생시킨 후에 실행될 메서드를 정의한다.

메서드 내에서는 호출된 메서드의 이름과 인자들을 가져와서 출력한다.

예외 객체를 확인하여 어떤 예외가 발생했는지에 따라 다른 메시지를 출력한다.


AroundAdvice

@어노테이션

 Aspect

    반복적으로 발생하는 관심사를 분리하여 모듈화한다.

Around

  ⇨ 대상 메서드를 실행할 때 전/후 처리 및 호출 결과를 가로채고 변경할 수 있는 어드바이스를 정의할 때 사용된다.

  ⇨ 호출된 메서드의 실행 전/후에 추가적인 작업을 수행할 수 있다.

코드

@Service
@Aspect
public class AroundAdvice {
	
	@Around("PointcutCommon.aPointcut")
	public Object aroundPrintLog(ProceedingJoinPoint pjp) throws Throwable {
		
		String methodName=pjp.getSignature().getName();
		
		System.out.println("[BEFORE]");
		
		StopWatch sw=new StopWatch();
		
		sw.start();
		
		Object obj=pjp.proceed();
		// 비즈니스 메서드가 수행됨
		
		sw.stop();
		
		System.out.println("[AFTER]");
		
		System.out.println("비즈니스 메서드 : "+methodName);
		
		System.out.println("수행하는데에 걸린시간 : "+sw.getTotalTimeMillis()+"(ms)초");
		
		return obj;
		
	}
	
}

설명

◎ @Aspect을 통해 Aspect로 동작함을 나타낸다.

@Around을 사용하여 PointcutCommon.aPointcut이라는 포인트컷에 해당하는 메서드가 실행될 때 수행될 어드바이스를 정의한다.