스프링/스프링 AOP

어노테이션으로 AOP 사용

chanhee01 2023. 9. 23. 21:25

@Trace 인터페이스

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Trace {
}

@Trace라는 어노테이션을 붙이면 자동으로 Aspect로 되어서 로그를 찍는 기능을 만들어볼 것이다.

 

 

 

TraceAspect.class

@Slf4j
@Aspect
public class TraceAspect {

    @Before("@annotation(hello.aop.exam.annotation.Trace)")
    public void doTrace(JoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();
        log.info("[trace] {} args={}", joinPoint.getSignature(), args);
    }
}

@Before 어노테이션으로 로직이 실행되기전에 로그를 출력해주는 AOP를 만든다.

 

 

 

Repository.class

@Repository
public class ExamRepository {

    private static int seq = 0;

    /**
     * 5번에 1번 실패하는 요청
     */
    @Trace
    public String save(String itemId) {
        seq++;
        if (seq % 5 == 0) {
            throw new IllegalStateException("예외 발생");
        }
        return "ok";
    }
}

 

 

Service.class

@Service
@RequiredArgsConstructor
public class ExamService {

    private final ExamRepository examRepository;

    @Trace
    public void request(String itemId) {
        examRepository.save(itemId);
    }
}​

 

Repository와 Service의 로직에 @Trace라는 어노테이션을 붙여주기만 하면 aop가 들어가서 로직이 실행되기 전에 로그를 찍어준다. 물론 TraceAspect.class를 빈으로 등록해줘야한다.

 

아래의 test 코드에서 @Import로 등록해줬다.

@Slf4j
@Import(TraceAspect.class)
@SpringBootTest
public class ExamTest {

    @Autowired
    ExamService examService;

    @Test
    void test() {
        for (int i = 0; i < 5; i++) {
            log.info("client request i={}", i);
            examService.request("data" + i);
        }
    }
}

테스트 코드인데 로직이 실행되기 전에 로그가 먼저 찍히는 것을 확인할 수 있다.

 

실제로 사용할 때에는 이렇게 스프링 AOP를 사용하면 된다.