Spring-AOP

이호영·2022년 2월 16일
0

Spring

목록 보기
8/18

AOP(Asept Oriented Programing) 관점지향프로그래밍
-스프링 어플리케이션은 특별한 경우를 제외하고 MVC웹 어플리케이션에서는 Web Layer, Business Layer, Data Layer로 정의

Web Layer: REST API를 제공하며 client 중심의 로직 적용
Business Layer: 내부 정책에 따른 logic을 개발하며 주로 해당 부분 개발
Data Layer: 데이터 베이스 및 외부와의 연동을 처리
Aspect: 자바에서 널리 사용하는 AOP 프레임워크에 포함되며 AOP를 정의하는 Class에 할당

주요 annotation
Pointcut: 기능을 어디에 적용시킬지 AOP를 적용 시킬 지점을 설정
Before: 메소드 실행하기 이전
After: 메소드가 성공적으로 실행 후 예외가 발생 되더라도 실행
AfterReturing: 메소드 호출 성공 실행 시(Not Throws)
AfrerThrowing: 메소드 호출 실패 예외 발생(Throws)
Around: Before/After 모두 제어

package com.example.aop.controller;

import com.example.aop.Dto.User;
import com.example.aop.annotation.Decode;
import com.example.aop.annotation.Timer;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api")
public class RestApiController {
    @GetMapping("/get/{id}")
    public String get(@PathVariable long id, @RequestParam String name){
        System.out.println("get method");
        System.out.println("get method"+id);
        System.out.println("get method"+name);
        return id+" "+name;
    }
    @PostMapping("/post")
    public User post(@RequestBody User user){
        System.out.println("post method"+user);
        return user;
    }
    @Timer
    @DeleteMapping("/delete")
    public void delete() throws InterruptedException {
        Thread.sleep(1000*2);
    }
    @Decode
    @PutMapping("/put")
    public User put(@RequestBody User user){
        System.out.println("put");
        System.out.println(user);
        return user;
    }
}
package com.example.aop.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
public class ParameterAop {
    @Pointcut("execution(* com.example.aop.controller..*.*(..))") 
    //특정 컨트롤러,서비스, 패키지 하위로 설정
    private void cut(){

    }
    @Before("cut()")
    public void befor(JoinPoint joinPoint){
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
     Method method=methodSignature.getMethod();
        System.out.println(method.getName());
        Object[] args=joinPoint.getArgs();
     for(Object obj:args){
         System.out.println("Type : "+ obj.getClass().getSimpleName());
         System.out.println("value : "+ obj);
     }
    }
    @AfterReturning(value = "cut()", returning = "ReturnObj")
    public void afterReturn(JoinPoint joinPoint, Object ReturnObj){
        System.out.println("Return obj");
        System.out.println(ReturnObj);
    }
}
package com.example.aop.aop;

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

@Aspect
@Component
public class TimerAop {
    @Pointcut("execution(* com.example.aop.controller..*.*(..))") 
    //특정 컨트롤러,서비스, 패키지 하위로 설정
    private void cut() {}
    @Pointcut("@annotation(com.example.aop.annotation.Timer)")//시간 로깅
    private void enableTime(){}
    @Around("cut() && enableTime()")
    public void around(ProceedingJoinPoint joinPoint) throws Throwable {
        StopWatch stopWatch= new StopWatch();
        stopWatch.start(); //타이머 시작
        Object result= joinPoint.proceed();
        stopWatch.stop(); //타이머 종료
        System.out.println("Total second: "+stopWatch.getTotalTimeSeconds());
    }
}
package com.example.aop.aop;

import com.example.aop.Dto.User;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.util.Base64;

@Aspect
@Component
public class DecodeAop {
    @Pointcut("execution(* com.example.aop.controller..*.*(..))") //특정 컨트롤러,서비스, 패키지 하위로 설정
    private void cut() {}
    @Pointcut("@annotation(com.example.aop.annotation.Decode)")//시간 로깅
    private void enableDecode(){}
    @Before("cut() && enableDecode()")
    public void before(JoinPoint joinPoint) throws UnsupportedEncodingException { //디코딩
        Object[] args= joinPoint.getArgs();
        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){   //인코딩
        if(returnObj instanceof User){
            User user= User.class.cast(returnObj);
            String email = user.getEmail();
            String Base64Email=Base64.getEncoder().encodeToString(email.getBytes());
            user.setEmail(Base64Email);   }
    }
}
package com.example.aop;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.http.converter.json.GsonBuilderUtils;

import java.util.Base64;

@SpringBootApplication
public class AopApplication {

    public static void main(String[] args) {

        SpringApplication.run(AopApplication.class, args);
        System.out.println(Base64.getEncoder().encodeToString("Steve@naver.com".getBytes()));
    }

}

0개의 댓글