Custom Annotation 으로 잘못짜여진 Aspect 개선

KHoney·2022년 8월 4일
0

Java

목록 보기
4/10
post-thumbnail

생성, 수정, 삭제 등 변경사항이 생길때 마다 내용을 DB 에 저장하는 기능으로 짜여진 코드인데, 굉장히 읽기 힘들고 비효율적인 것 같아 변경 하였다.

기존 코드를 간략히 보면…

어떤 request 가 들어오든 methodLogger 메소드가 동작하면서, 함수 이름으로 구별하여 Logging 한다.

굉장히 비효율 적이고, Controller, 서비스 단에서의 함수이름을 이 코드에 맞춰 써야하기도하고,

Controller 단에서의 함수이름과, Service 단의 함수 이름이 겹칠경우 중복으로 로깅하기도 하는 요상한 코드다… (왜 이런짓을)

기존 AnnotationLoggingAspect.java

@Aspect
@Component
@Slf4j
public class AnnotationLoggingAspect {
  @Autowired
  private AuditService auditService;

  @Autowired
  private HttpSession session;

	@Before("execution(* *..web.*Controller.*(..)) or execution(* *..*ServiceImpl.*(..))")
	public void methodLogger(JoinPointthisJoinPoint) {
	    String className =thisJoinPoint.getTarget().getClass().getName();
	    Object[] args =thisJoinPoint.getArgs();
	    StringBuffer argSb = new StringBuffer();
	    argSb.append("\n ******************************************************");
	    UserVO user = (UserVO) session.getAttribute("user");
	    boolean isModify = false;
	    argSb.append("\n * " + className + "." +thisJoinPoint.getSignature().getName() + "()");
			// 여기서 실행 하는 함수가 Logging 을 적용해야 하는 함수인지를 Method 이름으로 구분한다...
	    if(thisJoinPoint.getSignature().getName().contains("insert") ||thisJoinPoint.getSignature().getName().contains("set") ||thisJoinPoint.getSignature().getName().contains("create")
	        ||thisJoinPoint.getSignature().getName().contains("add")  ||thisJoinPoint.getSignature().getName().contains("update") ||thisJoinPoint.getSignature().getName().contains("copy")
	        ||thisJoinPoint.getSignature().getName().contains("delete")){
	        isModify = true;
	    }
	    StringBuilder argument = new StringBuilder();
	    for (int i = 0; i < args.length; i++, argument.append(" | ")) {
	        argSb.append("\n * " + (i + 1) + " arg's value : " + args[i]);
	        argument.append(args[i]);
	    }
	    argSb.append("\n ******************************************************");
	    if(isModify){        	
	        LogVO logVO = new LogVO();
	        logVO.setUserId(user.getUserId());
	        logVO.setName(thisJoinPoint.getSignature().getName());
	        logVO.setArguments(argument.toString());
	        auditService.createCallLog(logVO);
	        log.info(user.getUserId()+ ": Modify :"+ logVO.getName() + " by "+argument.toString());
	    }
	    if (log.isDebugEnabled()) {
	        log.debug(argSb.toString());
	    }
	}
}

개선하기

메소드 이름으로 구분했던 저장 유무를,

Annotation 이 있는 경우면 로깅하려고 한다.

로깅에 사용할 Annotation @CreateCallLog 생성

// CreateCallLog.java
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CreateCallLog {
}

Aspect, 수행 할 함수 변경
request 가 성공적으로 끝났을때 만 저장하기 위해서
@Before Annotation 을 @AfterReturning 으로 변경한다.
따로 Validation 이 필요하지 않기 때문에 로그 저장만 딱 해준다.

AnnotationLoggingAspect.java

	@AfterReturning("@annotation(CreateCallLog)")
	public void createCallLog(JoinPoint jp) throws Throwable {        
	    String methodName = jp.getSignature().getName();
	    Object[] args = jp.getArgs();
	    StringBuilder argument = new StringBuilder();
        // 기존에 argument를 저장하는 방식은 유지해준다.        
        for (int i = 0; i < args.length; i++, argument.append(" | ")) {
	        argument.append(args[i]);
	    }
	    UserVO user = (UserVO) session.getAttribute("user");
	    LogVO logVO = LogVO.builder() // Builder 로 변경
	            .userId(user.getUserId())
	            .name(methodName)
	            .arguments(argument.toString())
	            .build();
	    auditService.createCallLog(logVO);		
	}
profile
좋은 개발자가 되고싶은

0개의 댓글