mingg IT

[Spring] AOP custom annotation 사용하기 본문

BackEnd

[Spring] AOP custom annotation 사용하기

mingg123 2021. 11. 18. 17:13

큰 프로젝트를 진행하다 보면 특정 서비스에 대헤서 디버깅을 붙고싶을 경우가 있다.

 

이럴때 사용할 수 잇는게 custom annotation이다.

 

우선 

/annotation/Decode.java 를 생성한다.

 Decode.java 

package com.example.aop.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.annotation.Retention;

@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface Timer {

}

 

2. /aop/DecodeAop.java 를 생성한다.

 

DecodeAop.java

package com.example.aop.aop;

import java.util.Base64;

import com.example.aop.dto.User;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

@Aspect
@Component
public class DecodeAop {
    @Pointcut("execution(* com.example..*.*(..))")
    private void cut() {

    }

    @Pointcut("@annotation(com.example.aop.annotation.Decode)")
    private void enableDecode() {
    }

    // @Around("cut() && enableTimer()")
    @Before("cut() && enableDecode()")
    public void before(JoinPoint joinPoint) throws Throwable {
        Object[] args = joinPoint.getArgs();
        System.out.println("before event");

        for (Object arg : args) {
            if (arg instanceof User) {
                User user = User.class.cast(arg);
                String base64Email = user.getEmail();
                String email = new String(Base64.getDecoder().decode(base64Email), "UTF-8");
                user.setEmail(email);
            }
        }

    }

    @AfterReturning(value = "cut() && enableDecode()", returning = "returnObj")
    public void afterReturn(JoinPoint joinPoint, Object returnObj) {
        System.out.println("after event");
        if (returnObj instanceof User) {
            User user = User.class.cast(returnObj);
            String email = user.getEmail();
            String base64Email = Base64.getEncoder().encodeToString(email.getBytes());
            user.setEmail(base64Email);

        }

        System.out.println(returnObj);
    }
}

 

 

 

3. RestApiController.java 에서 만들었던 해당 annotation을 사용한다.

RestApiController.java

package com.example.aop;

import com.example.aop.annotation.Decode;
import com.example.aop.annotation.Timer;
import com.example.aop.dto.User;

import org.springframework.util.StopWatch;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/aopexample")
@RestController
public class RestApiController {

    @Decode
    @PutMapping("/put")
    public User put(@RequestBody User user) {
        System.out.println("put");
        System.out.println(user);
        return user;
    }
}

 

 

4. Talend API에서 request를 보낸다.

(참고로 난 server.port : 9090임)

 

 

5. 확인한다.

 

 

request로 base64Encode된 email을 보내더라도 before event에서 decode 해주었기 때문에 put method에서 email이 알맞는 형식으로 들어갔고, 

after event에서 다시 encode 해주었기 때문에 다음과 같이 결과가 나타남을 알 수 있다. 

 

이를 이용해서 디버깅을 한다던가 특정 서비스에 대해서 request를 받기전, 받고난 후 등 처리를 할 수 있다. 

Comments