Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spring AOP를 사용한 로깅과 권한 제어 #25

Open
since1909 opened this issue Nov 24, 2024 · 3 comments
Open

Spring AOP를 사용한 로깅과 권한 제어 #25

since1909 opened this issue Nov 24, 2024 · 3 comments
Assignees
Labels
CS 리스트 백엔드 질문 리스트의 직무 구분을 위한 라벨

Comments

@since1909
Copy link
Member

since1909 commented Nov 24, 2024

📝 Spring AOP를 사용한 로깅과 권한 제어

📚 주제:
Spring 의 AOP 기능 소개 및 활용 방법

🎯 스터디 목표
Spring AOP 기능에 대해 이해하고, 현재 서비스에서 사용되고 있는 방식에 대해 설명한다.


📖 핵심 내용:

1️⃣ AOP

🔍 AOP 란?

AOP 는 "Aspect-Oriented Programming" 의 약자로 핵심 비즈니스 로직과 횡단 관심사(cross-cutting concerns) 를 분리하여 코드의 모듈성과 재사용성을 높이는 프로그래밍 기법입니다.

말 그대로 관점을 기준으로 프로그래밍을 하겠다는 소리입니다. 관점을 기준으로 로직을 모듈화 해 분리하고 동일한 관점을 가지는 코드에 반복 사용할 수 있도록 해줍니다. 이때 동일한 관점을 가지는 여러 소스코드를 횡단 관심사 라고 부릅니다. AOP 는 이렇게 흩어진 횡단 관심사를 하나로 모아주는 역할을 합니다.

AOP : Aspect(관점) 을 기준으로 로직을 모듈화 해서 비지니스 로직과 분리하여 재사용하겠다.

보통 AOP는 핵심 로직과 분리된 부가 기능을 모듈화 하는 케이스가 많기 때문에 로깅, 보안, 트렌잭션 등의 기능에 많이 사용됩니다.

🖍 Spring AOP

Spring 은 Proxy 패턴을 사용해서 AOP 를 사용합니다. 런타임에 스프링이 프록시 객체 생성을 통해 AOP 를 주입하게 됩니다. 빈 초기화 시에 AOP 들이 프록시 객체로 생성되고 실제 사용되는 타이밍에 해당하는 Bean 메소드를 호출할 수 있게 됩니다.

용어 정리

  • Aspect: 횡단 관심사를 캡슐화한 모듈입니다.
  • Join Point: 어플리케이션 실행 중 특정 지점을 의미합니다. Spring AOP에서는 주로 메서드 호출 시점이 Join Point가 됩니다.
  • Advice: Join Point에서 실행되는 작업입니다. Advice는 실행 시점에 따라 다음과 같이 나뉩니다:
    • Before: 메서드 실행 전에 실행
    • After: 메서드 실행 후에 실행
    • Around: 메서드 실행 전후에 실행
    • After Returning: 메서드가 정상적으로 실행된 후에 실행
    • After Throwing: 메서드 실행 중 예외가 발생한 후에 실행
  • Pointcut: Advice가 적용될 Join Point를 정의하는 표현식입니다. 특정 패키지, 클래스, 메서드 등에 대해 설정할 수 있습니다.
  • Weaving: Advice를 실제 코드에 적용하는 과정입니다. Spring AOP는 런타임 기반 프록시를 사용해 Weaving을 수행합니다.

2️⃣ 서비스 활용 예시

1. LoggingAspect

백으로 들어오는 Request 를 로깅하기 위한 모듈입니다.
request 요청을 처리하기 전후로 실행 시간, 결과값등을 로깅하기 위해 @ Around 를 사용했습니다.

@Aspect
@Component
public class LoggingAspect {

    @Pointcut("within(com.sparrow.cloud.backend.controller..*)")
       public void onRequest() {
       }

    @Around("onRequest()")
    public Object logExecution(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        
        // 메서드 이름과 파라미터 로깅
        System.out.println("Method: " + joinPoint.getSignature());
        System.out.println("Args: " + Arrays.toString(joinPoint.getArgs()));

        Object result;
        try {
            result = joinPoint.proceed(); // 실제 메서드 실행
        } finally {
            long elapsedTime = System.currentTimeMillis() - startTime;
            System.out.println("Execution time: " + elapsedTime + "ms");
        }
        
        return result;
    }
}
  • joinPoint : controller 메소드
  • joinPoint.proceed() : joinPoint 로 들어온 관점을 실행시킵니다. 여기서는 컨트롤러 메소드를 실행시켜줍니다.

2. ProjectAuthAspect

프로젝트 조회 권한을 검사하기 위한 모듈입니다.
여러개의 controller 에서 프로젝트 조회를 수행하는데 권한 검사를 한 곳에서 하기 위해 Aspect를 도입했습니다.
컨트롤러 메소드 실행 전에 해당 사용자에게 권한이 있는지를 확인 합니다.

@Before("execution(* com.backend.controller.RestController.selectNext(..)) || " +
            "execution(* com.backend.controller.RestController.selectPrevious(..))")
public void getAuthorizationForDetail(JoinPoint joinPoint) {
    Object[] args = joinPoint.getArgs();
    for (Object arg : args) {
        if (arg instanceof RequestXX) {
            if ( /* 관리자 권한이면 */ ) {
                return;
            } else if ( /* 특정 사용자 권한이면 */ ) {
                // 인증 수행
               }
            }
        }
    }
}
  • @ Before : 표현식에 해당하는 메소드 전에 실행합니다.
  • joinPoint : 설정한 관점이 매개변수로 들어옵니다. 여기에서는 controller 메소드가 됩니다.
  • 메소드의 args 를 가져와 권한 검사를 수행합니다.

💡 참고 자료:

  • 링크나 참고한 자료 출처를 여기에 적어 주세요.
@since1909 since1909 added 백엔드 질문 리스트의 직무 구분을 위한 라벨 CS 리스트 labels Nov 24, 2024
@since1909 since1909 added this to the 4주차(11/25 월) milestone Nov 24, 2024
@since1909 since1909 self-assigned this Nov 24, 2024
@since1909 since1909 changed the title Spring AOP를 사용한 로깅과 권한 제어 AOP를 사용한 로깅과 권한 제어 Nov 25, 2024
@since1909 since1909 changed the title AOP를 사용한 로깅과 권한 제어 Spring AOP를 사용한 로깅과 권한 제어 Nov 25, 2024
@jokbalkiller
Copy link
Member

AOP 라는 개념에 대해 알게되어서 좋았습니다. 멋진 방법인 것 같아요!

@suna-ji
Copy link
Member

suna-ji commented Nov 25, 2024

스프링이 내부적으로 너무 많은 것을 처리해주다 보니 세부 동작과 원리를 놓칠 때가 많았는데, 이번 지식 공유를 통해 다시 한 번 배울 수 있어서 정말 좋았습니다!💕🫡

@yuiseo
Copy link
Member

yuiseo commented Nov 25, 2024

AOP라는 개념을 처음 알게 되어 흥미로웠습니다. 게다가 모듈화를 스프링 내부적으로 어노테이션을 지원해주는 것이 신기했습니다. 그래서 next.js에서도 사용하는 분들이 있는지 알아보니, ssr을 처리할 때도 해당 개념을 사용하는 분들도 계시더라구요! 새로운 것을 알게 되는 좋은 발표였습니다! 감사합니다!

@yuiseo yuiseo closed this as completed Nov 25, 2024
@suna-ji suna-ji reopened this Dec 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CS 리스트 백엔드 질문 리스트의 직무 구분을 위한 라벨
Projects
None yet
Development

No branches or pull requests

4 participants