AOP_Annotation

jinkyung·2021년 2월 15일
0

Spring

목록 보기
10/24

Annotation사용을 위해 xml 파일 설정


LogAdvice

package com.springbook.biz.common;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Service;


@Service	//bean을 생성 
@Aspect		//Aspect = Pointcut + Advice 
public class LogAdvice {

	
	// 메소드가 아니라 표현식(execution..)에 대한 이름을 설정한 것이다.(id)
	@Pointcut("execution(* com.springbook.biz..*Impl.*(..))")
	public void allPointcut() {
		
	}
	@Pointcut("execution(* com.springbook.biz..*Impl.get*(..))")
	public void getPointcut() {
		
	}
	
	//모든 메서드 실행 전에 printLog 실행
	@Before("allPointcut()")
	public void printLog(JoinPoint jp) {
		System.out.println("[공통 로그] 비즈니스 로직 수행 전 동작");
	}
}


BeforeAdvice

package com.springbook.biz.common;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Service;

@Service	
@Aspect // 결합하겠다는 뜻 
public class BeforeAdvice {
	
	@Pointcut("execution(* com.springbook.biz..*Impl.*(..))")
	public void allPointcut() {}
	
	
	@Before("allPointcut()")
	public void beforeLog(JoinPoint jp) {
		String method = jp.getSignature().getName();
		Object[] args = jp.getArgs();
		
		System.out.println("[사전 처리] " + method + 
				"() 메서드 ARGS 정보 : " + args[0].toString());
		
		//System.out.println("[사전 처리] 비즈니스 로직 수행 전 동작");
	}
}


AfterReturningAdvice

package com.springbook.biz.common;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Service;

import com.springbook.biz.user.UserVO;

@Service
@Aspect
public class AfterReturningAdvice {
	
	@Pointcut("execution(* com.springbook.biz..*Impl.get*(..))")
	public void getPointcut() {}
	
	@AfterReturning(pointcut="getPointcut()", returning="returnObj")
	public void afterLog(JoinPoint jp, Object returnObj) {
		String method = jp.getSignature().getName();

		if(returnObj instanceof UserVO) {
			UserVO user = (UserVO)returnObj;
			if(user.getRole().equals("Admin")) {
				System.out.println(user.getName() + " 로그인(Admin)");
			}
		}
		
		// 연결된 모든 메서드의 정보를 출력해준다
		System.out.println("[사후 처리] " + method + 
				"() 메서드 리턴값 : " + returnObj.toString());
		
		//System.out.println("[사후 처리] 비즈니스 로직 수행 후 동작");
	}
}


AfterThrowingAdvice

package com.springbook.biz.common;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Service;

@Service
@Aspect
public class AfterThrowingAdvice {
	
	@Pointcut("execution(* com.springbook.biz..*Impl.*(..))")
	public void allPointcut() {}
	
	@AfterThrowing(pointcut="allPointcut()", throwing="exceptObj")
	public void exceptionLog(JoinPoint jp, Exception exceptObj) {
		
		String method = jp.getSignature().getName();
		System.out.println("[예외 처리] " + method +
				"() 메서드 수행 중 발생된 예외 메시지 : " + exceptObj.getMessage());
                
                
     		//디테일한 예외 종류 처리 
		if(exceptObj instanceof IllegalArgumentException) {
			System.out.println("부적합한 값이 입력되었습니다");
		}else if(exceptObj instanceof NumberFormatException) {
			System.out.println("숫자 형식의 값이 아닙니다");
			
		//Exception의 순서는 마지막에 와야한다. 모든 예외의 부모클래스이기 때문이다. 
		}else if(exceptObj instanceof Exception) {
			System.out.println("문제가 발생했습니다");
		}
	}
}


예외 발생을 위한 코드 추가



AfterAdvice

@Service
@Aspect
public class AfterAdvice {
	
	@Pointcut("execution(* com.springbook.biz..*Impl.*(..))")
	public void allPointcut() {}
	
	@After("allPointcut()")
	public void finallyLog() {
		System.out.println("[사후 처리] 비즈니스 로직 수행 후 무조건 동작");
	}
}


AroundAdvice

@Service
@Aspect
public class AroundAdvice {
	
	@Pointcut("execution(* com.springbook.biz..*Impl.*(..))")
	public void allPointcut() {}
	
	@Around("allPointcut()")
	public Object aroundLog(ProceedingJoinPoint pjp) throws Throwable{
		String method = pjp.getSignature().getName();
		
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		
		Object obj = pjp.proceed();
		
		stopWatch.stop();
		System.out.println(method + "() 메서드 수행에 걸린 시간 : " + 
						stopWatch.getTotalTimeMillis() + "(ms)초");
		
		return obj;
	}
}


pointcut을 한군데에 몽땅 몰아넣자

PointcutCommon

package com.springbook.biz.common;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class PointcutCommon {
	@Pointcut("execution(* com.springbook.biz..*Impl.*(..))")
	public void allPointcut() {}

	@Pointcut("execution(* com.springbook.biz..*Impl.get*(..))")
	public void getPointcut() {}
	
	
}

BeforeAdvice

@Service
@Aspect
public class BeforeAdvice {
	
	@Before("PointcutCommon.allPointcut()")
	public void beforeLog(JoinPoint jp) {
		String method = jp.getSignature().getName();
		Object[] args = jp.getArgs();
		
		System.out.println("[사전 처리] " + method + 
				"() 메서드 ARGS 정보 : " + args[0].toString());
	}
}

AfterReturningAdvice

@Service
@Aspect
public class AfterReturningAdvice {
	
	
	@AfterReturning(pointcut="PointcutCommon.getPointcut()", returning="returnObj")
	public void afterLog(JoinPoint jp, Object returnObj) {
		String method = jp.getSignature().getName();

		if(returnObj instanceof UserVO) {
			UserVO user = (UserVO)returnObj;
			if(user.getRole().equals("Admin")) {
				System.out.println(user.getName() + " 로그인(Admin)");
			}
		}
		
		// 연결된 모든 메서드의 정보를 출력해준다
		System.out.println("[사후 처리] " + method + 
				"() 메서드 리턴값 : " + returnObj.toString());
		
		//System.out.println("[사후 처리] 비즈니스 로직 수행 후 동작");
	}
}

0개의 댓글