본문 바로가기

Spring/Core

(43)
[AOP] 스프링 AOP 기술의 한계 이전 장(링크)까지 스프링 AOP를 사용할 때 발생할 수 있는 문제에 대해서 알아보았다. 이번 장에서는 프록시 기술과 한계에 대해서 알아보도록 한다. 모든 코드는 깃허브(링크) 에 올려두었다. 프록시 기술과 한계 - 타입 캐스팅 JDK 동적 프록시와 CGLIB를 사용해서 AOP 프록시를 만드는 방법에는 각각 장단점이 존재한다. JDK 동적 프록시는 인터페이스가 필수이고, 인터페이스를 기반으로 프록시를 생성한다. 반면 CGLIB는 구체 클래스를 기반으로 프록시를 생성한다. 인터페이스가 없고 구체 클래스만 있는 경우에는 CGLIB를 사용해야 한다. 하지만 인터페이스가 있는 경우에는 JDK 동적 프록시나 CGLIB 둘중에 하나를 선택할 수 있다. 스프링이 프록시를 만들 때 제공하는 ProxyFactory에 p..
[Core] AOP 실무 적용 이전 장(링크)까지 스프링 AOP 포인트컷의 지시자에 대해서 알아보았다. 이번 장에서는 실제 실무에서 사용될만한 예제를 만들어보는 시간을 가져본다. 모든 코드는 깃허브(링크) 에 올려두었다. 예제 코드 이번 장에서 우리의 목표는 아래와 같은 애너테이션을 생성하여 프로젝트에 적용시키는 것이다. @Trace: 애너테이션으로 로그를 출력 @Retry: 애너테이션으로 예외 발생시 재시도 AOP를 적용하기 위해 간단히 Service, Repositry 클래스를 작성해본다. ExamRepository @Repository public class ExamRepository { private static int seq = 0; public String save(String itemId) { seq++; if (seq ..
[Core] AOP 내부 호출 문제 이전 장(링크)까지 스프링 AOP를 실제 실무에 적용시키는 방법에 대해서 알아보았다. 이번 장에서는 AOP 내부 호출 문제에 대해서 알아보도록 한다. 모든 코드는 깃허브(링크) 에 올려두었다. 프록시와 내부 호출 문제 스프링은 프록시 방식의 AOP를 사용하기 때문에 AOP를 적용하려면 항상 프록시를 통해서 대상 객체(Target)을 호출해야 한다. 이런 방식으로 해야 프록시에서 먼저 어드바이스를 호출하고, 이후에 대상 객체를 호출한다. 만약 프록시를 거치지 않고 대상 객체를 직접 호출하게 되면 AOP가 적용되지 않고, 어드바이스도 호출되지 않는다. AOP를 적용하면 스프링은 대상 객체 대신에 프록시를 스프링 빈으로 등록한다. 따라서 스프링은 의존관계 주입시에 항상 프록시 객체를 주입한다. 프록시 객체가 ..
[Core] 포인트컷 지시자 - bean, this, target 이전 장(링크) 에서는 within, args, @target, @within, @annotation, @args 지시자에 대해서 알아보았다. 이번 장에서는 bean, this, target 지시자에 대해서 알아보도록 한다. 모든 코드는 깃허브(링크) 에 올려두었다. bean 스프링 전용 포인트컷 지시자로 빈의 이름으로 지정한다. 스프링 빈의 이름으로 AOP 적용 여부를 지정한다. 스프링에서만 사용할 수 있는 특별한 지시자다. bean(orderService) || bean(*Repository)와 같은 문법으로 사용된다. *와 같은 패턴을 사용할 수 있다. BeanTest @Slf4j @SpringBootTest @Import(BeanTest.BeanAspect.class) public class Be..
[Core] 포인트컷 지시자 - within, args, @target, @within ... 이전 장(링크) 에서는 스프링 AOP의 포인트컷과 execution 지시자에 대해서 알아보았다. 이번 장에서는 within, args, @target, @within, @annotation, @args 지시자에 대해서 알아보도록 한다. 모든 코드는 깃허브(링크) 에 올려두었다. within within 지시자는 특정 타입 내의 조인 포인트에 대한 매칭을 제시한다. 해당 타입이 매칭되면 그 안의 메서드(조인 포인트)들이 자동으로 매칭된다. 문법이 단순하며 execution에서 타입 부분만 사용한다고 보면 된다. public class WithinTest { AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); Method helloMe..
[Core] 포인트컷 지시자 - execution 이전 장(링크) 에서는 스프링 AOP를 적용하는 방법에 대해서 알아보았다. 이번 장에서는 스프링 AOP의 포인트컷에 대해서 알아보도록 한다. 모든 코드는 깃허브(링크) 에 올려두었다. 포인트컷 지시자 "포인트컷 표현식"을 포함한 "포인트컷"에 대해서 자세하게 알아본다. AspectJ는 포인트컷을 편리하게 표현하기 위한 특별한 표현식을 제공한다. (예. @Pointcut("execution(* com.roy.spring.aop.order..*(..))")) 포인트컷 표현식은 "AspectJ pointcut expression"으로 AspectJ가 제공하는 포인트컷 표현식을 줄인 것을 의미하는 것이다. 포인트컷 지시자 포인트컷 표현식은 execution같은 포인트컷 지시자(Pointcut Designator..
[Core] AOP 구현 - 심화 이전 장(링크) 에서는 스프링 AOP를 적용하는 기본적인 방법에 대해서 알아보았다. 이번 장에서는 복잡한 상황에서 스프링 AOP를 적용하는 방법을알아보도록 한다. 모든 코드는 깃허브(링크) 에 올려두었다. 어드바이스 추가 마치 트랜잭션 기능이 추가되는 것과 같이 로그를 출력해보도록 한다. 트랜잭션 기능은 일반적으로 아래와 같은 기능을 제공해야 한다. 핵심 로직 실행 직전에 트랜잭션을 시작 핵심 로직 실행에 문제가 없으면 커밋 핵심 로직 실행에 예외가 발생하면 롤백 @Slf4j @Aspect public class AspectVersion3 { @Pointcut("execution(* com.roy.spring.myaop.order..*(..))") private void allOrder() { } @Po..
[Core] AOP 구현 - 기본 이전 장(링크) 에서는 스프링 AOP의 개념에 대해서 알아보았다. 이번 장에서는 스프링 AOP를 적용하는 기본적인 방법에 대해서알아보도록 한다. 모든 코드는 깃허브(링크) 에 올려두었다. 예제 프로젝트 스프링 AOP를 구현하기 위해 예제 프로젝트를 만들어본다. OrderRepository @Slf4j @Repository public class OrderRepository { public String save(String itemId) { log.info("[orderRepository] 실행"); if (itemId.equals("exception")) { throw new IllegalStateException("예외 발생!"); } return "ok"; } } OrderService @Slf4j ..