TIL&WIL
2023-07-28 TIL (Spring AOP)
blues_jun
2023. 7. 28. 20:58
오늘 공부한 내용
- 내배캠 강의
- 내배캠 플러스 주차 개인과제 (Spring AOP적용)
- 프로그래머스 알고리즘 문풀
AOP적용
Spring AOP는 관점 지향 프로그래밍을 의미하는데 개념만 들었을 때에는 실제로 많이 와닿지가 않았다.
오늘 실습을 해보면서 조금 감을 잡은 것 같다.
AOP는 게시글, 댓글 수정/삭제시에 본인이 작성하지 않았으면은 예외를 던지는 곳에 적용했다.
작성한 코드는 다음과 같다.
@Aspect
@Component
@RequiredArgsConstructor
public class RoleCheckAop {
private final BlogRepository blogRepository;
private final CommentRepository commentRepository;
@Pointcut("execution(* com.sparta.blog.service.BlogService.updateBlog(..))")
private void updateBlog() {}
@Pointcut("execution(* com.sparta.blog.service.BlogService.deleteBlog(..))")
private void deleteBlog() {}
@Pointcut("execution(* com.sparta.blog.service.CommentService.updateComment(..))")
private void updateComment() {}
@Pointcut("execution(* com.sparta.blog.service.CommentService.deleteComment(..))")
private void deleteComment() {}
@Around("updateBlog() || deleteBlog()")
public Object blogRoleCheck(ProceedingJoinPoint joinPoint) throws Throwable {
// 게시글 정보 받아오기
Long blogId = (Long) joinPoint.getArgs()[0];
Blog blog = blogRepository.findById(blogId).orElseThrow(() -> new NoExistBlogException("해당 게시글이 존재하지 않습니다."));
// 로그인된 유저 정보 받아오기
UserDetailsImpl userDetails = (UserDetailsImpl) joinPoint.getArgs()[1];
User user = userDetails.getUser();
if (!user.getRole().equals(UserRoleEnum.ADMIN) || blog.getAuthor().equals(user.getUsername())) {
throw new NoPermissionException("본인이 작성한 게시글만 수정/삭제할 수 있습니다.");
}
return joinPoint.proceed();
}
@Around("updateComment() || deleteComment()")
public Object commentRoleCheck(ProceedingJoinPoint joinPoint) throws Throwable {
// 댓글 정보 받아오기
Long blogId = (Long) joinPoint.getArgs()[0];
Long commentId = (Long) joinPoint.getArgs()[1];
Comment comment = commentRepository.findByIdAndBlogId(commentId, blogId);
// 로그인된 유저 정보 받아오기
UserDetailsImpl userDetails = (UserDetailsImpl) joinPoint.getArgs()[2];
User user = userDetails.getUser();
if(comment == null) throw new NoExistCommentException("해당 댓글이 존재하지 않습니다.");
if (!(user.getRole().equals(UserRoleEnum.ADMIN) || comment.getUsername().equals(user.getUsername()))) {
throw new NoPermissionException("자신이 등록한 댓글만 수정/삭제할 수 있습니다.");
}
return joinPoint.proceed();
}
}
@Pointcut 으로 aop의 적용 위치를 정해주고, @Around를 이용하여 해당 메서드가 실행될 때 aop가 수행될 수 있도록 했다.
내부 코드는 ProceedingJoinPoint를 활용하여 해당 인자값(게시글, 댓글, 유저 정보 등)을 받아와서 활용했다.
이렇게 적용하니 Service부분은 비즈니스 로직에 더욱 집중할 수 있고, 반복되는 코드들이 많이 사라져서 코드의 가독성이 더 좋아졌다고 느껴졌다.