https://code-learning.tistory.com/109
day66) [AOP] - 로깅 처리하기1
[AOP] - 관점 지향 프로그래밍 (때가 되면 알아서 동작할 수 있게 만든다) - 공통로직을 분리하기 위해 공통 로직과 (횡단 관심) + 핵심로직 (비즈니스 메서드)로 나누어 처리한다. - 기능을 하
code-learning.tistory.com
앞서 했던 로깅처리는 어떤 핵심관심(비즈니스 메서드, CRID)이 실행되는지 알지 못한다.
어드바이스(횡단관심, 공통로직)를 효율적으로 사용하려면 핵심관심을 알아 활용해야한다.
-> JoinPoint(사용자측에서 사용하는 '모든 비즈니스 메서드') 인터페이스를 활용해보자.
++
-> xml로 aspect(결합)했던 로깅을 @(어노테이션)으로 변경해보자
[JoinPoint 인자]
기존의 인자를 받지 않았던 LogAdvice.java에서 JoinPoint 인터페이스를 인자로 받으면 어떤 핵심관심인지, 사용되는 인자가 무엇인지 알 수 있다.
public void beforeLog(JoinPoint jp) {
// jp -> 어떤 핵심관심이 호출되었는지에대한 정보가 담겨있음!
String methodName=jp.getSignature().getName();
System.out.println("호출된 핵심관심: "+methodName);
Object[] args=jp.getArgs();
System.out.println("사용된 인자");
for(Object v:args) {
System.out.println(v);
}
}
[Object returnObj]
시점이 AfterReturning일 때 사용가능하다. 핵심관심 수행 완료후 return(반환값)을 볼 수 있다.
public void arLog(JoinPoint jp,Object returnObj) {
// Object returnObj : 바인드 변수 -> 컨테이너에게 설정을 해주어야한다!!!
System.out.println("afterReturning 로그");
String methodName=jp.getSignature().getName();
System.out.println("호출된 핵심관심: "+methodName);
System.out.println("반환값: "+returnObj);
if(returnObj instanceof MemberVO) { // 캐스팅 가능여부를 확인하는 로직
MemberVO vo= (MemberVO)returnObj; // 다운캐스팅
if(vo.getRole().equals("ADMIN")) {
System.out.println("+++++ ADMIN +++++");
}
else {
System.out.println(" 일반사용자 입장 ");
}
}
else if(returnObj instanceof BoardVO) {
System.out.println("Board정보를 반환받았습니다.");
}
else {
System.out.println("알수없는 반환값입니다.");
}
}
[Object returnObj]
시점이 AfterThrowing일때 사용 가능하다. 핵심관심 수행중 오류가 나타났을때의 오류정보를 사용할 수 있다.
public void atLog(JoinPoint jp,Exception excepObj) {
String methodName=jp.getSignature().getName();
System.out.println("호출된 핵심관심: "+methodName);
System.out.println("반환된 예외: "+excepObj);
if(excepObj instanceof IllegalArgumentException) {
System.out.println("실습을위해서 일부러 예외를 만든상황입니다.");
}
else if(excepObj instanceof NumberFormatException) { // 예외 확인후 추가가능
System.out.println("타입이 올바르지않습니다.");
}
else if(excepObj instanceof Exception) {
System.out.println("미확인 예외발생!!!");
}
}
[ProceedingJoinPoint pjp]
시점이 around일때 사용 가능하다.
around : 핵심로직의 전체를 주관할 수 있다. 필터와 유사하게 동작함!
핵심관심을 인자로 받아와서 앞뒤작업을 수행함!!
->모든 around관련 어드바이스는 ProceedingJoinPoint (pjp)가 인자로 반드시 존재해야한다.
public Object aroundLog(ProceedingJoinPoint pjp) throws Throwable {
StopWatch sw=new StopWatch();
sw.start();
Object obj=pjp.proceed(); // 수행할 핵심관심
sw.stop();//수행시간을 알 수 있다.
String methodName=pjp.getSignature().getName();
System.out.println("호출된 핵심관심: "+methodName);
System.out.println("걸린시간: "+sw.getTotalTimeMillis());
return obj;
}
[어노테이션을 사용한 횡단관심]
1. @을 사용할 것이라고 설정하면서 시작!
-applicationContext.xml-
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
2. @Pointcut 설정
어드바이스에 포인트컷을 설정
"참조 메서드" : 로직이 비어있음. 식별을 목적으로 하기 때문
각각의 로그가 같은 포인트 컷을 참조하고 있기 때문에 클래스를 따로 빼보자!
-pointcutCommon
package com.test.app.common;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class PointcutCommon {
@Pointcut("execution(* com.test.app..*Impl.*(..))")
public void aPointcut() {} // 참조 메서드
@Pointcut("execution(* com.test.app..*Impl.get*(..))")
public void bPointcut() {}
}
3. 어드바이스의 동작시점을 설정하는 @
참조메서드를 이용
4. aspect 결합, 객체화
-LogAdvice.java
package com.test.app.common;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Service;
import org.springframework.util.StopWatch;
import com.test.app.board.BoardVO;
import com.test.app.member.MemberVO;
@Service
@Aspect // == 4. 결합 : 포인트컷 + 어드바이스
public class LogAdvice {
@Before("PointcutCommon.bPointcut()")//3. 어드바이스의 동작시점을 설정하는 @
public void beforeLog(JoinPoint jp) {
// jp -> 어떤 핵심관심이 호출되었는지에대한 정보가 담겨있음!
System.out.println("beforeLog");
String methodName=jp.getSignature().getName();
System.out.println("호출된 핵심관심: "+methodName);
Object[] args=jp.getArgs();
System.out.println("사용된 인자");
for(Object v:args) {
System.out.println(v);
}
}
@AfterReturning(pointcut="PointcutCommon.bPointcut()",returning="returnObj")//3. 어드바이스의 동작시점을 설정하는 @
public void arLog(JoinPoint jp,Object returnObj) {
// Object returnObj : 바인드 변수 -> 컨테이너에게 설정을 해주어야한다!!!
System.out.println("afterReturning 로그");
String methodName=jp.getSignature().getName();
System.out.println("호출된 핵심관심: "+methodName);
System.out.println("반환값: "+returnObj);
if(returnObj instanceof MemberVO) { // 캐스팅 가능여부를 확인하는 로직
MemberVO vo= (MemberVO)returnObj; // 다운캐스팅
if(vo.getRole().equals("ADMIN")) {
System.out.println("+++++ ADMIN +++++");
}
else {
System.out.println(" 일반사용자 입장 ");
}
}
else if(returnObj instanceof BoardVO) {
System.out.println("Board정보를 반환받았습니다.");
}
else {
System.out.println("알수없는 반환값입니다.");
}
}
@AfterThrowing(pointcut="PointcutCommon.aPointcut()",throwing="excepObj")
public void atLog(JoinPoint jp,Exception excepObj) {
String methodName=jp.getSignature().getName();
System.out.println("호출된 핵심관심: "+methodName);
System.out.println("반환된 예외: "+excepObj);
if(excepObj instanceof IllegalArgumentException) {
System.out.println("실습을위해서 일부러 예외를 만든상황입니다.");
}
else if(excepObj instanceof NumberFormatException) { // 예외 확인후 추가가능
System.out.println("타입이 올바르지않습니다.");
}
else if(excepObj instanceof Exception) {
System.out.println("미확인 예외발생!!!");
}
}
@Around("PointcutCommon.aPointcut()")//3. 어드바이스의 동작시점을 설정하는 @
public Object aroundLog(ProceedingJoinPoint pjp) throws Throwable {
StopWatch sw=new StopWatch();
sw.start();
Object obj=pjp.proceed(); // 수행할 핵심관심
sw.stop();//수행시간을 알 수 있다.
String methodName=pjp.getSignature().getName();
System.out.println("호출된 핵심관심: "+methodName);
System.out.println("걸린시간: "+sw.getTotalTimeMillis());
return obj;
}
}
'Spring > Spring' 카테고리의 다른 글
day69) annotation 사용하기2 - Controller관련 (0) | 2022.04.07 |
---|---|
day68) Spring - Model 설계2 : JDBC Template (0) | 2022.04.07 |
day66) [AOP] - 횡단관심: 로깅 처리하기1 (0) | 2022.04.04 |
day65) Spring-Controller 설계2:DispatcherServlet-servlet.xml @로 변경하기 (0) | 2022.04.04 |
day64) Spring-Controller설계1 (0) | 2022.03.31 |
댓글