Spring

[AOP] .xml 설정을 @(어노테이션)으로 변경하는법

Clearing 2022. 9. 18. 11:27
728x90

.xml의 설정을 @(어노테이션)으로 변경하기 위해서는 스프링 컨테이너에게 AOP 설정을

@으로 변경할 거라고 <aop:aspectj-autoproxy></aop:aspectj-autoproxy>를 통해 알려줘야 한다.

 

결합(aspect)을 위해서는 포인트 컷과 횡단 관심이 필요하다.

 

1) 포인트컷 설정

- 연결하고자하는 횡단 관심이 작성된 클래스에서 설정 가능

   ex) @Pointcut("execution(아웃풋 패키지명.클래스명.메서드명.(인자))")

 

2) aop 조건 설정

- 수행할 메서드에 조건 설정

@Before("실행할 포인트 컷의 메서드")
@After("실행할 포인트컷의 메서드")
@Around("실행할 포인트컷의 메서드")
@AfterReturning(pointcut="실행할 포인트컷의 메서드", returning="반환받을 객체명")
@AfterThrowing(pointcut="실행할 포인트컷의 메서드", throwing="반환받을 객체명")

 

예시

package com.kim.biz.common;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Service;
import org.springframework.util.StopWatch;

// around로 사용할 advice는 반드시 pjp를 input으로 가져야한다!!
// ex) 필터 서블릿 클래스

@Service
@Aspect
public class AroundAdvice {
	
	
	@Around("PointcutCommon.aPointcut()")
	public Object printLogAround(ProceedingJoinPoint pjp) throws Throwable {		
		
		String methodName = pjp.getSignature().getName();
		// 현재 수행중인 포인트컷(핵심로직,CRUD)의 메서드명
		System.out.println("수행중인 핵심메서드명: "+methodName);
		
		StopWatch sw = new StopWatch();
		sw.start();
		
		Object returnObj = pjp.proceed(); // 수행해야할 포인트컷
		// pjp.proceed()에 의해 비즈니스 메서드가 수행됨!
		sw.stop();
		System.out.println("수행시간: "+sw.getTotalTimeMillis()+"ms");
		
		return returnObj;
	}
}

 

package com.kim.biz.common;

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


@Service
@Aspect
public class AfterThrowingAdvice {
	
	
	@AfterThrowing(pointcut="PointcutCommon.aPointcut()", throwing="exceptObj")
	public void printLogAfterThrowning(JoinPoint jp,Exception exceptObj) {
		String methodName = jp.getSignature().getName();
		// 현재 수행중인 포인트컷(핵심로직,CRUD)의 메서드명
		Object[] args = jp.getArgs();
		// 현재 수행중인 포인트컷(핵심로직,CRUD)이 사용하는 인자들의 정보

		System.out.println("수행중인 핵심메서드명: "+methodName);
		System.out.println("사용하는 인자");
		System.out.println("=========");
		for(Object v:args) {
			System.out.println(v);
		}
		System.out.println("=========");
		
		System.out.println("발생한 예외: "+exceptObj.getMessage());
		if(exceptObj instanceof IllegalArgumentException) {
			System.out.println("올바르지 않은 인자값.....");
		}
		else if(exceptObj instanceof NumberFormatException) {
			System.out.println("숫자 형식이 아닌 값....");
		}
		else if(exceptObj instanceof Exception) {
			System.out.println("예외가 발생...");
		}
		else {
			System.out.println("확인되지 않은 에러 발생!!!");
		}
	}
	
}

 

3) 결합시킬 클래스 객체화 후 Aspect라고 지정
@Service
@Aspect

포인트 컷을 별도로 클래스화하여 관리 가능하며 해당 클래스에도 @Aspect를 붙여줘야 한다.

포인트 컷을 클래스화 했다면 aop 조건 설정 시 메서드명 앞에 클래스명을 붙여준다

ex) @Before("클래스명.실행할 포인트 컷의 메서드")

 

포인트컷 클래스화 예시

package com.kim.biz.common;

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

@Aspect
public class PointcutCommon {

	@Pointcut("execution(* com.kim.biz..*Impl.*(..))")
	public void aPointcut() {}
	
	@Pointcut("execution(* com.kim.biz..*Impl.select*(..))")
	public void bPointcut() {}
	
}
728x90

'Spring' 카테고리의 다른 글

MVC 패턴의 변화  (0) 2022.09.20
스프링 JDBC 설정  (0) 2022.09.19
[AOP] JoinPoint와 바인드 변수  (0) 2022.09.17
AOP(관점 지향 프로그래밍)  (0) 2022.09.16
어노테이션(@)을 이용한 의존성 주입  (0) 2022.09.15