Spring 44

[Spring] JDK 동적 프록시와 CGLIB의 한계

이전 포스팅에서 포인트컷 지시자 중 `this`와 `target`을 다루며 한 가지 주의사항을 이야기했었다.JDK 동적 프록시는 인터페이스를 상속받은 프록시 객체를 스프링 빈으로 등록하기 때문에, *구체 클래스 타입으로 타입 캐스팅이 불가능하다는 점이다.* 당시에 "이런 유사한 이유로 스프링은 CGLIB를 기반으로 프록시 객체를 생성하도록 기본값을 설정했을까?" 의문을 가졌었는데 본 포스팅에서 자세히 이야기해보고자 한다.1. JDK 동적 프록시와 CGLIB의 차이점표면적인 차이점은 이미 이야기한 바와 같다. JDK 동적 프록시의 경우, 인터페이스를 상속받은 프록시 객체가 생성되기 때문에 *자식 타입으로는 캐스팅이 불가능하다.*반면, CGLIB의 경우 구체 클래스를 상속받은 프록시 객체가 생성되기 때문에 ..

Spring 2024.05.12

[Spring] 포인트컷 지시자 (AspectJ Pointcut Expression) - 3

포인트컷 지시자에 관한 마지막 포스팅이다.이번 포스팅에서는 커스텀 애노테이션을 생성해 포인트컷 표현식으로 활용할 수 있는 방법과 어드바이스에 다양한 매개변수를 전달해 활용하는 방법에 대해 알아볼 것이다. 1. 예제 세팅먼저 커스텀 애노테이션을 생성하자.@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface ClassAop {}@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface MethodAop { String value();} `ClassAop`의 경우 클래스 레벨에 붙일 애노테이션으로, @Target의 값을 `ElementT..

Spring 2024.05.11

[Spring] 포인트컷 지시자 (AspectJ Pointcut Expression) - 2

직전 포스팅에서는 포인트컷 지시자 중 `execution`, `within`, `args`에 관한 문법에 대해 알아봤다.이들은 표현식을 사용해 대상 타입이나 메서드 이름, 파라미터 타입 등을 지정했다. 이번 포스팅은 대상 타입만을 지정하는 `this`와 `target`지시자에 대해 알아볼 것이다. 1. 차이점기본적으로 `this`와 `target` 모두 대상 타입을 지정한다는 점에서 공통점이 있다.단순히 타입 하나를 지정하면 되는데 차이점은 뭘까? `this`는 스프링 빈으로 등록되어 있는 *프록시 객체*를 대상으로 포인트컷 매칭을 시도한다.`target`은 *실제 타겟*을 대상으로 포인트컷 매칭을 시도한다.이게 무엇을 의미할까?  우선 기본적으로 스프링은 별도의 설정이 없다면 CGLIB를 기반으로 프..

Spring 2024.05.10

[Spring] 포인트컷 지시자 (AspectJ Pointcut Expression) - 1

이전 포스팅에서 포인트컷은 주로 `AspectJExpressionPointcut`을 사용한다고 이야기했다.예제로 사용해봤던 `NameMatchMethodPointcut`을 사용할 수 도 있지만, 복잡한 상황까지 범용적으로 사용하기는 부족했다. `AspectJExpressionPointcut`은 실제 AspectJ 프레임워크가 제공하는 포인트컷 표현식을 활용해 AOP를 적용할 조인 포인트를 설정할 수 있다.  가장 많이 사용하는 `execution`부터 여러 포인트컷 지시자를 사용하는 문법을 알아보도록 하자. 1. 예제 세팅간단한 예제로 `MemberService` 인터페이스를 상속받는 `MemberServiceImpl` 클래스를 만든다.public interface MemberService { St..

Spring 2024.05.10

[Spring] 스프링 AOP 예제 구현

지난 포스팅까지 직접 ProxyFactory를 사용해 프록시를 생성하는 단계부터 AutoProxyCreator, 그리고 AOP의 개념에 대해 공부했다. 이제 간단한 예제 프로젝트를 통해 스프링 AOP를 활용해 부가 기능을 적용해보자.  1. 예제 세팅예제 프로젝트는 간단하게 하나의 Service 계층 클래스와 Repository 클래스로 구성된다.@Slf4j@Service@RequiredArgsConstructorpublic class OrderService { private final OrderRepository orderRepository; public void orderItem(String itemId) { log.info("[orderService] 실행"); ..

Spring 2024.05.09

[Spring] @RequestBody로 매핑하는 객체에 기본 생성자는 필수일까?

의문`@RequestBody`를 통해 DTO를 매핑시킬 때 큰 생각없이 `Setter` 및 `기본 생성자`를 사용했었다. 기본 생성자를 통해 객체를 생성하고, Setter를 통해 필드 값을 주입하지 않을까? 라고 생각했기 때문이다. 다양한 블로그에서 잘 소개되어있지만, 위의 예상과는 조금 다르게 마치 JPA 처럼 `리플렉션`을 통해 매핑이 진행된다.기본 생성자는 필요하다. 하지만 이후 필드값은 리플렉션을 통해 매핑된다. 그렇기에 Setter는 필요없다. 기본 생성자가 없어도 동작되던데..?위의 결론에 따르면 기본 생성자는 필수이다. 하지만 프로젝트를 진행하던 중 기본 생성자 없이도 오류 없이 동작하는 모습을 확인할 수 있었다.@Getterpublic class LogInDto { private St..

Spring 2024.05.05

[Spring] 스프링 AOP 개념

1. AOP(Aspect-Oriented Programming)이란? - 핵심 기능과 부가 기능 부가 기능을 분리하기 위해 다양한 디자인 패턴부터, 스프링이 제공하는 자동 프록시 생성기까지 알아봤다. 드디어! AOP에 대해 학습할 시간이다. 애플리케이션의 로직은 크게 핵심 기능과 부가 기능으로 나눌 수 있다. 핵심 기능 해당 객체가 제공하는 고유의 기능이다. 각 계층에서 수행하는 실제 고유한 로직이다. 부가 기능 핵심 기능을 보조하기 위해 제공되는 기능이다. 로그 추적 로직, 일부 계층에서의 트랜잭션 기능 등이 있다. 부가 기능은 단독으로 사용되지 않는다. 핵심 기능과 버무러져 사용된다. 그런데 만약, 핵심 기능과 부가 기능이 하나의 클래스에 작성되어 있다면? 끔찍하다! 공통된 부가 기능을 여러 클래스에..

Spring 2024.03.07

[Spring] @Aspect

이전 포스팅에서는 스프링 애플리케이션에서 자동 프록시 생성기(AutoProxyCreator)를 통해 프록시를 적용하기위해 필요한 어드바이저를 직접 생성해 스프링 빈으로 등록해주는 과정을 거쳤다. 스프링은 `@Aspect` 애노테이션으로 매우 편리하게 포인트컷과 어드바이스로 구성되어있는 어드바이저 생성 기능을 지원한다! @Slf4j @Aspect public class LogTraceAspect { private final LogTrace logTrace; public LogTraceAspect(LogTrace logTrace) { this.logTrace = logTrace; } @Around("execution(* hello.proxy.app..*(..))") public Object execute(P..

Spring 2024.03.07

[Spring] AutoProxyCreator (스프링이 제공하는 빈 후처리기)

1. 자동 프록시 생성기(AutoProxyCreator) 이전 포스팅에서 스프링이 자동으로 등록해주는 빈 후처리기가 있다고 소개하며 마무리했었다. 해당 기능 및 스프링 AOP을 사용하려면 build.gradle에 다음과 같이 AOP에 관한 의존성을 추가해줘야한다. implementation 'org.springframework.boot:spring-boot-starter-aop' `AnnotationAwareAspectJAutoProxyCreator`라는 빈 후처리기가 자동으로 등록된다. 이 빈 후처리기는 스프링 빈으로 등록된 어드바이저를 자동으로 모두 찾아, 프록시가 필요한 곳에 자동으로 프록시를 적용한다. 이전 시간에 이야기했던 것처럼 직접 basePackage를 지정해주는 필터를 만드는게 아니라, ..

Spring 2024.03.06

[Spring] 빈 후처리기, BeanPostProcessor

1. 빈 후처리기? 일반적인 상황에서는 컴포넌트 스캔을 통해 스프링 빈을 등록하게 되면 실제 객체가 등록된다. 당연한 것이다. Configuration 파일을 통해 직접 수동으로 프록시 객체를 등록하지 않는 이상 스프링 컨테이너에는 실제 객체가 등록된다. 이러한 상황에서, 빈 후처리기라는 것은 스프링 컨테이너에 실제 스프링 빈을 등록하기 전 다양한 작업을 할 수 있다. 객체를 조작 완전히 다른 객체로 바꿔치기도 가능 이러한 빈 후처리기를 이용한다면, Configuration 파일의 모든 빈에 하나하나 프록시 설정을 해줬던 모습을 지울 수 있지 않을까? 혹은 컴포넌트 스캔을 통해 자동으로 등록하는 스프링 빈에 대해서 프록시로 바꿔치기할 수 있지 않을까? 직접 알아보자! 먼저 빈 후처리기는 `BeanPost..

Spring 2024.03.06