먼저 springboot 환경셋업이 필요합니다.

환경셋업은 아래 링크 참고 부탁드립니다.

 

https://vmpo.tistory.com/7?category=730732

 

intellij SpringBoot(인텔리제이 스프링부트) 시작하기 - hello world 브라우저에 출력하기(gradle)

intellij SpringBoot(스프링부트) hello world 출력하기 @intellij 기준으로 진행하겠습니다 @Gradle 프로젝트로 진행하는 이유는 빌드 속도도 maven보다 빠르고 import 라이브러리도 한눈에 볼 수 있어 개발시에..

vmpo.tistory.com

springboot로 개발환경을 갖췄다면  본격적으로 AspectJ를 적용해보도록하겠습니다.

 

특정 메소드 실행 전, 실행 후, exception발생시 등 메소드 전 후의 특정 로직을 수행해야 할 경우

활용할 수 있습니다.

ex) 소스 변경으로 인한 영향도 없이 전체 페이지 진입로그를 저장해야할 경우

 

순서대로 진행하면 Aspectj를 쉽게 적용가능합니다.

전체 코드는 제일 하단에 추가해두었습니다.

1. AspectJ 라이브러리 환경설정

 

아래와 같이 build.gradle 파일에 dependencies 영역에

 

implementation 'org.springframework.boot:spring-boot-starter-aop' 를 추가해줍니다.

 

*springboot의 경우 위 설정만 하더라도 바로 적용가능합니다.

 

2. @Aspect 적용 클래스 생성

AspectJ는 신규 클래스에 @Aspect 어노테이션만 적용해주면 쉽게 사용가능합니다.

 

URL 진입처리를 할 Controller class 1개와 aspectJ를 적용할 class 1개를 각각 아래와 같이 생성하겠습니다.

 

TestConroller는 localhost:8080/test 를 브라우저에서 입력하면, Hello World를 출력하는 간단한 메소드 하나를 정의해두었습니다.

LogAopHelperCLS 클래스에는 @Aspect 어노테이션과 @Componet 어노테이션을 추가해줍니다.

 

이제 LogAopHelperCLS 클래스에  http://localhost:8080/test 호출시 로그를 생성할 수 있는 코드를 작성해보겠습니다.

 

먼저, 코드 작성 전 아래 내용에 대한 이해가 필요합니다.

 

아래 @어노테이션을 LogAopHelperCLS 클래스 즉, @AspectJ어노테이션에 선언된 클래스의 메소드에 선언해주면,

특정 함수 실행 전후의 특정 처리가 가능합니다.

 

 

@Pointcut : aspectJ를 적용할 타겟을 정의해준다. 전체 컨트롤러의 함수대상, 특정 어노테이션을 설정한 함수대상, 

                특정 메소드 대상 등 개발자가 적용하길 원하는 범위를 정의하는 어노테이션

@Before : aspectJ를 적용할 타겟 메소드가 실행되기 '전' 수행됨

@AfterReturning : aspectJ를 적용할 타겟 메소드가 실행된 '후' 수행됨 (제일 마지막에 수행됨)

@Around : aspectJ를 적용할 타겟 메소드 실행 전 , 후 처리를 모두 할 수 있음

 

그럼 아래와 같이 단순히 실행 전후에 콘솔 로그만 찍어내는 코드를 작성해보겠습니다.

 

아래코드에서,

@Pointcut 어노테이션은 GetMapping어노테이션이 선언된 메소드에만 aspectj가 적용되도록 제한하고 있습니다.

그리고, @Before, @AfterReturning, @Around 어노테이션에서는 파라미터로 GeMapping()함수를 선언해

해당 범위에 적용할 수 있도록 환경을 만들어주었습니다. 

 

그럼 이제 아래 클래스만 있으면 springboot에서 @GetMapping 어노테이션이 있는 메소드에 aspectj 적용이 가능합니다.

package com.example.c32.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LogAopHelperCLS {

    private static final Logger LOGGER = LoggerFactory.getLogger(LogAopHelperCLS.class);

    /**
     *   @GetMapping 설정된 메소드 또는 클래스 설정
     *   GetMapping 노테이션이 설정된 특정 클래스/메소드에만 AspectJ가 적용됨.
     */
    @Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping)")
    public void GetMapping(){ }

    /**
     * @param joinPoint
     */
    @Before("GetMapping()")
    public void before(JoinPoint joinPoint) {
        LOGGER.info("=====================AspectJ TEST  : Before Logging Start=====================");
        LOGGER.info("=====================AspectJ TEST  : Before Logging End=====================");
    }

    /**
     * @param joinPoint
     * @param result
     */
    @AfterReturning(pointcut = "GetMapping()", returning = "result")
    public void AfterReturning(JoinPoint joinPoint, Object result) {
        LOGGER.info("=====================AspectJ TEST  : AfterReturning Logging Start=====================");
        LOGGER.info("=====================AspectJ TEST  : AfterReturning Logging END=====================");
    }

    /**
     *
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around("GetMapping()")
    public Object Around(ProceedingJoinPoint joinPoint) throws Throwable {
        LOGGER.info("=====================AspectJ TEST  : Around Logging Start=====================");
        try {
            Object result = joinPoint.proceed();
            LOGGER.info("=====================AspectJ TEST  : Around Logging END=====================");
            return result;
        }catch (Exception e) {
            LOGGER.error("=====================AspectJ Around Exception=====================");
            LOGGER.error(e.toString());
            return null;
        }
    }

}

 

서버 빌드후 실행해보겠습니다.

 

위와 같이 test url입력시 LogAopHelperCLS에서 정의한 Log를 콘솔에서 확인 할 수 있습니다.

 

@Around시작 -> @before시작,종료 -> @Around종료 -> @AfterReturning시작,종료 순서로 실행되는 것을 확인 할 수 있습니다.

 

@Around어노테이션의 시작 종료는 Object result = joinPoint.proceed(); 전후로 나뉩니다.

디버깅을 해보면 joinPoint.proceed() 가 실제 타겟 함수 실행 결과를 처리하고 있습니다.

 

위 로직을 응용하면, 특정 url진입시 로그 삽입, 암호화된 파라미터가 있는 url에 대해 복호화처리를

@aspect가 선언된 클래스에서 처리할 수 있어 효율적인 설계가 가능할 것 같습니다.

LIST
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기