스프링/스프링 AOP
-
HTTP 요청 응답 기록 - httpexchanges스프링/스프링 AOP 2023. 10. 1. 14:25
HTTP 요청과 응답의 과거 기록을 확인하는 엔드포인트는 httpexchanges이다. HttpExchangeRepository 인터페이스의 구현체를 빈으로 등록하면 httpexchanges 엔드포인트를 사용할 수 있다. -> 해당 빈을 등록하지 않으면 httpexchanges 엔드포인트가 활성화 되지 않는다 스프링 부트는 기본으로 InMemoryHttpExchangeRepository 구현체를 제공한다. @SpringBootApplication public class ActuatorApplication { public static void main(String[] args) { SpringApplication.run(ActuatorApplication.class, args); } @Bean public..
-
AOP 주의사항 - 프록시와 내부 호출스프링/스프링 AOP 2023. 9. 23. 23:27
스프링은 프록시 방식의 AOP를 사용하기 때문에 AOP를 적용하기 위해서는 항상 프록시를 통해서 대상 객체를 호출해야 한다. AOP 를 적용하면 스프링은 대상 객체 대신에 프록시를 스프링 빈으로 등록한다. 스프링은 의존관계 주입시에 항상 프록시 객체를 주입하기 때문에 대상 객체를 직접 호출하는 문제는 일반적으로 발생하지 않지만 대상 객체의 내부에서 메서드 호출이 발생하면 프록시를 거치지 않고 대상 객체를 직접 호출하는 문제가 발생하는 경우가 있다. 이해하기 쉽게 코드로 설명하겠다. CallLogAspect.class @Slf4j @Aspect public class CallLogAspect { @Before("execution(* hello.aop.internalcall..*.*(..))") public..
-
재시도 AOP스프링/스프링 AOP 2023. 9. 23. 21:48
단순 조회를 할 때 아주 가끔씩 간헐적으로 예외가 발생하는 경우가 있다. 단순 조회이기 때문에 그냥 새로고침을 눌러주면 된다. 이럴 때에는 재시도 AOP를 만들어서 예외가 가끔 발생하더라도 다시 재시도를 해주면 된다. Retry 어노테이션 @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Retry { int value() default 3; } Retry 어노테이션을 선언해줄 때 int value() default 3;이라는 변수를 선언해준다. 이 변수는 RetryAspect에서 재시도를 하는 default 값으로 사용될 것이다. RetryAspect.class @Slf4j @Aspect public cla..
-
어노테이션으로 AOP 사용스프링/스프링 AOP 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={}", joinPoin..
-
포인트컷 - execution스프링/스프링 AOP 2023. 9. 23. 17:47
execution의 매칭 조건 execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?namepattern(param-pattern) throws-pattern?) 위의 코드가 포인트컷의 매칭 조건이다. ?가 붙은 것들은 생략을 할 수 있다. pointcut.setExpression("execution(public String hello.aop.member.MemberServiceImpl.hello(String))"); 아무것도 생략을 하지 않았을 때의 경우이다. 매칭 조건 - (?)가 붙은 것들은 생략 가능 접근제어자(?) : public 반환타입 : String 선언타입(?) : hello.aop.member.MemberService..
-
어드바이스 종류스프링/스프링 AOP 2023. 9. 22. 20:55
@Around : 메서드 호출 전후에 수행, 조인 포인트 실행 여부 선택, 반환 값 변환 ,예외 변환 등 가능 @Before : 조인 포인트 실행 이전에 실행 @AfterReturning : 조인 포인트가 정상 완료후 실행 @AfterThrowing : 메서드가 예외를 던지는 경우 실행 @After : 조인 포인트가 정상 또는 예외에 관계없이 실행(finally) 2. @Before @Before("hello.aop.order.aop.Pointcuts.orderAndService()") public void doBefore(JoinPoint joinPoint) { log.info("[before] {}", joinPoint.getSignature()); } @Before 어노테이션은 조인 포인트 실행 이..
-
어드바이스 순서스프링/스프링 AOP 2023. 9. 22. 20:10
@Order 어노테이션을 이용해서 순서를 줄 수 있다. 그런데 이 어노테이션은 메서드에 부여하는 것이 아니라 클래스에 부여하는 것이다. 클래스 레벨의 @Aspect에 부여되는 것이니 @Aspect 안에 있는 두 개의 메서드에 @Order()를 넣는다해도 순서가 정해지지 않는다. @Slf4j public class AspectV5Order { // hello.aop.order 패키지와 하위 패키지 @Pointcut("hello.aop.order.aop.Pointcuts.allOrder()") // 포인트컷 private void allOrder(){} // 클래스 이름 패턴이 *Service @Pointcut("hello.aop.order.aop.Pointcuts.orderAndService()") pri..
-
@Pointcut - 포인트컷 분리스프링/스프링 AOP 2023. 9. 22. 14:36
AOP 동작을 위한 service, repository 코드 OrderRepository.class @Slf4j @Repository public class OrderRepository { public String save(String itemId) { log.info("[orderRepository] 실행"); //저장 로직 if (itemId.equals("ex")) { throw new IllegalStateException("예외 발생!"); } return "ok"; } } OrderService.class @Slf4j @Service public class OrderService { private final OrderRepository orderRepository; public OrderSer..