[Spring] 커스텀 어노테이션

2024. 10. 23. 00:32·Spring

팀 프로젝트의 Spring 이관 작업을 진행하면서, 지속적으로 사용해야 하는 Cookie 정보를 가져오기 위해 request와 response를 매번 받아와야 하는 방식에 대해 고민하게 되었다. 이 접근 방식이 적절한지 궁금해지던 중, 커스텀 어노테이션에 대한 개념을 알게 되었다.


 

기본적으로 제공되는 어노테이션 외에도, 필요에 따라 자신만의 커스텀 어노테이션을 정의할 수 있다.

커스텀 어노테이션이란, 말 그대로 내가 어노테이션을 직접 만들어 사용할 수 있는 어노테이션을 말한다.

 

이번 포스팅에서는 커스텀 어노테이션을 만드는 방법과 그 사용 예시, 장단점에 대해 알아보겠다.


커스텀 어노테이션 정의

커스텀 어노테이션을 정의하려면, @interface 키워드를 사용하여 새로운 어노테이션 타입을 만들어야 한다. 아래는 @LoginCheck라는 커스텀 어노테이션의 예시이다.

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

@Target(ElementType.METHOD) // 메서드에 적용
@Retention(RetentionPolicy.RUNTIME) // 런타임에 유지
public @interface LoginCheck {
    String value() default "user"; // 기본값 설정
}

 

위의 코드에서 @Target은 이 어노테이션이 적용될 수 있는 대상을 지정하고, @Retention은 어노테이션이 유지되는 범위를 설정한다.

RUNTIME으로 설정했기 때문에, 런타임 중에 이 어노테이션을 사용할 수 있다.


AOP와 커스텀 어노테이션

자바에서 커스텀 어노테이션을 정의하는 것 외에도, AOP를 활용하여 이 어노테이션에 기능을 추가할 수 있다. AOP는 비즈니스 로직과 공통 관심사를 분리하여 코드의 재사용성을 높이고 유지보수성을 개선하는 데 도움을 준다.

 

아래는 @LoginCheck 어노테이션을 사용하는 AOP의 예시 코드인 LoginAspect 클래스이다.

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

@Aspect
@Component
public class LoginAspect {

    @Around("@annotation(LoginCheck의 경로.LoginCheck)") // @LoginCheck 어노테이션이 붙은 메서드에 적용
    public Object checkLogin(ProceedingJoinPoint joinPoint) throws Throwable {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getResponse();
        HttpSession session = request.getSession();

        // 로그인 정보 확인
        String[] loginInfo = checkLoginInformation(request, response, session);

        if (loginInfo[0] == null) {
            // 로그인되지 않은 경우 로그인 페이지로 리다이렉트
            return "redirect:login.do"; 
        }

        // 로그인된 경우 원래 메서드를 실행
        return joinPoint.proceed();
    }

    private String[] checkLoginInformation(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
        String[] loginInformation = new String[2]; // [MEMBER_ID, CREW_CHECK]

        // 쿠키에서 로그인 정보 가져오기
        Cookie[] cookies = request.getCookies();
        
        
        // 이하 생략

 

위의 LoginAspect 클래스는 @LoginCheck 어노테이션이 붙은 메서드에 대해 로그인 정보를 확인하고, 로그인되지 않은 경우에는 로그인 페이지로 리다이렉트하는 기능을 제공한다.

 

+ xml에 주입도 해놓아야 한다.

<!-- logincheck 주입 -->
	<bean id="loginAspect" class="***class 경로***.LoginAspect">
    	<constructor-arg ref="loginCheck" />
	</bean>

 

위처럼 사전작업을 하면, 내가 직접 만든 커스텀 어노테이션을 사용할 수 있다.

	@LoginCheck
	@PostMapping("/myPage.do")
	public String myPage(MemberDTO memberDTO, BoardDTO boardDTO,ReservationDTO reservationDTO, Model model, HttpSession session) {
		// 로그인된 사용자의 마이 페이지 처리

 


 

사용 시 장점

 

 

모듈화: 사용 시 관련된 기능을 모듈화할 수 있어, 각 모듈을 독립적으로 개발하고 테스트할 수 있다.

강력한 구조화: 어노테이션을 통해 특정한 비즈니스 로직을 명확하게 구조화할 수 있어, 팀원 간의 코드 이해도가 높아진다.

런타임 시 동적 기능 추가: AOP를 통해 코드 변경 없이 기존 코드에 새로운 기능을 동적으로 추가할 수 있다.

일관성: 특정 비즈니스 규칙을 어노테이션으로 정의하면, 코드 전체에서 일관되게 적용할 수 있어 개발 규칙이 명확해진다.

 

단점

 

가시성 감소: AOP를 사용하면 코드 흐름이 분산되어, 메서드의 동작 방식이 명확하지 않을 수 있다. 디버깅 시 실제 코드와 동작이 다를 수 있어 가독성이 떨어질 수 있다.

제한된 타입 검사: 커스텀 어노테이션의 경우, 어노테이션을 사용하는 메서드에서 기대하는 타입의 파라미터를 보장할 수 없어, 런타임 시 오류가 발생할 가능성이 있다.

복잡성 증가: AOP를 처음 접하는 개발자에게는 개념이 복잡하게 느껴질 수 있으며, 이를 이해하고 활용하는 데 추가적인 학습이 필요할 수 있다.

구현의 제약: AOP는 Java의 다중 상속을 지원하지 않기 때문에, 인터페이스를 통해 기능을 정의해야 하며, 이로 인해 설계가 복잡해질 수 있다.

 


 

커스텀 어노테이션과 AOP는 여러 장점과 단점을 가지고 있어, 프로젝트의 요구 사항과 팀의 개발 스타일에 따라 적절하게 활용하는 것이 중요하다.,,!

 

 

'Spring' 카테고리의 다른 글

[Spring] 쿠키 활용하기 - 자동 로그인  (0) 2024.10.25
[Spring] Multipart & 파일 업로드  (1) 2024.10.23
[Spring] AOP와 어노테이션  (0) 2024.10.16
[Spring] AOP 관점지향 프로그래밍  (1) 2024.10.15
[Spring] Ajax를 이용한 비동기 처리와 아이디 중복검사 구현  (0) 2024.10.14
'Spring' 카테고리의 다른 글
  • [Spring] 쿠키 활용하기 - 자동 로그인
  • [Spring] Multipart & 파일 업로드
  • [Spring] AOP와 어노테이션
  • [Spring] AOP 관점지향 프로그래밍
yn98
yn98
좌우명 : 여전할 것 인가, 역전할 것 인가? 백엔드 개발자가 되고싶은 역전하고 있는 개발자 꿈나무의 블로그입니다. 개발을 하면서 공부한 것들을 기록합니다. 24.06 ~
  • yn98
    개발 꿈나무
    yn98
  • 전체
    오늘
    어제
    • 분류 전체보기 (131)
      • Python (3)
      • 공부 (7)
      • DB (7)
      • JAVA (24)
      • JSP (9)
      • jQuery (2)
      • HTML (3)
      • Spring (20)
      • 웹 (4)
      • C (1)
      • Git (2)
      • 에러일기 (19)
      • 프로젝트 (6)
      • 책 (21)
        • 멘토씨리즈 자바 (14)
        • 2024 수제비 정보처리기사 (7)
      • 기타 (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • GitHub
    • Notion
  • 공지사항

  • 인기 글

  • 태그

    멘토씨리즈 자바
    정보처리기사 실기
    이벤트 스케줄러
    스프링 프레임워크
    jsp
    정처기
    @service
    오블완
    DispatcherServlet
    java
    @Component
    @repository
    aop
    상속
    오버로딩
    MVC
    티스토리챌린지
    정보처리기사
    2-layered 아키텍처
    codeup 4891 : 행복
    정처기 실기
    recoverabledataaccessexception
    어노테이션
    수제비
    Spring
    객체지향
    생성자
    html
    Di
    ViewResolver
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
yn98
[Spring] 커스텀 어노테이션
상단으로

티스토리툴바