Spring AOP 적용 - woowacourse-teams/2022-ternoko Wiki

터놓고 Spring AOP 적용 [노션으로 보기]

Pull Request - #246

Custom Annotation을 만들자.

터놓고에서는 @CrewOnly, @CoachOnly 두가지의 어노테이션을 구현하여 적용하였다. 코치 페이지에 접근하는 사용자가 코치가 맞는지, 크루 페이지에 접근하는 사용자가 크루가 맞는지 검증하는 로직을 AOP로 구현했고 각각의 기능을 Annotation으로 제공하기 위해 CustomAnnotation을 적용했다.

Custom Annotation을 만들어 사용하기 위해서는 @Target, @Retetion 어노테이션이 필요하다. 각각 Target은 어노테이션을 어디에 적용할지에 대해 지정하는 기능을 수행하고 Retention은 어느 범위까지 적용하는지 지정하기 위해 사용된다. Method 단위에서 쓰고자 Target은 ElementType.METHOD로 구현하고 서비스 동작 과정에 사용되는 어노테이션이기 때문에 RetentionPolicy.RUNTIME으로 설정했다.

🍀 @Target & @Retention - Custom Annotation

AOP를 구현하자.

@Aspect
@Component
@RequiredArgsConstructor
public class LoginMemberVerifier {

    private final MemberTypeCache memberTypeCache;

    @Before("@annotation(com.woowacourse.ternoko.login.aop.CrewOnly)")
    public void checkMemberTyeCrew() {
        final MemberType memberType = memberTypeCache.getMemberType();
        if (!memberType.equals(MemberType.CREW)) {
            throw new CrewNotAllowedException(CREW_NOT_ALLOWED);
        }
    }
}
  1. Aspect로 사용할 LoginMemberVerifier 클래스에 @Aspect 어노테이션을 사용하였다.
  2. 해당 기능을 수행하기 전에 메서드를 호출하고자 @Before 어노테이션을 사용했다.
  3. @Before 안에 Pointcut을 지정해주는데 CrewOnly라는 어노테이션이 달려있는 메서드로 지정해주었다.

동작

@CrewOnly가 적용된 메서드가 실행되면 실행 전 MemberType이 Crew인지 확인하는 AOP 메서드가 실행되며 성공하면 그대로 진행하고 아니면 Exception을 발생하도록 구현하였다.

🍀 AOP

MemberType을 Request Scope에 전달하자.

@RequestScope

@Component
@RequestScope
public class MemberTypeCache {
    private MemberType memberType;

    public MemberType getMemberType() {
        return memberType;
    }

    public void setMemberType(MemberType memberType) {
        this.memberType = memberType;
    }
}

현재 사용하고 있는 클래스로는 MemberTypeCache라는 클래스에 적용하여 사용 중이다. 사용 목적은 사용자가 어떤 요청을 했을 때 요청에 맞는 Member Type인지 확인하기 위한 데이터였다. (ex. Coach가 크루의 면담 예약 신청 페이지에 접속할 경우 Exception)

AOP 기능에 적용되어 사용 중이며 Context나 Session의 범위에 사용은 불필요하여 각각의 HTTP 요청마다 생성하여 비교하도록 @RequestScope를 사용하여 구현하였다.

🍀 @RequestScope

Slack Alarm도 AOP 적용하자.

기존 Event를 사용하여 구현했던 Slack 알람 기능을 AOP를 적용하도록 수정하였다.

목적

  1. Event에 대한 정확한 지식 없이 적용
  2. Event로 인한 테스트 코드 증가
  3. 기존 요구사항 충족
    • 면담 예약에 관련된 작업(생성, 수정, 삭제, 취소)을 할 때 Slack을 통해 알람을 보낸다.
    • 면담 예약하는 비즈니스 로직은 Slack으로 인한 서비스 장애가 발생하면 안된다.

이런 이유로 Event로 사용했던 코드를 걷어내고 AOP로 적용하여 프로젝트를 개선했다.

🍀 Slack 알람 AOP 적용