모르지 않다는 것은 아는것과 다르다.

Spring 39

Spring AOP 4편 (With Spring Transaction)

개요 3편에서는 Spring 트랜잭션(@Transactional)의 동작과정을 알아보았다. 4편에서는 @Transactional 어노테이션 처리 과정을 도식화하여 정리하고, 디버깅해보도록 하자. 나는 보통 코드를 분석할때, 애플리케이션 로딩 시점과 런타임 시점을 구분해서 분석한다. 좀 더 자세히 말하면 아래와 같이 구분할 수 있다. 먼저 애플리케이션 로딩 시점과 런타임 시점으로 나눌 수 있고, 로딩 시점에는 자동구성을 하는 시점과 스프링 컨테이너가 세팅되는 시점으로 나누어 보았다. 자동구성에는 이번에 알아볼 Spirng AOP 관련된 자동구성과 Spring Transaction 관련된 자동구성에 대해서만 알아보도록 하겠다. 사실 이것보다 훨씬더 깊고 복잡하지만, 나는 우선 이정도로만 Spring AOP와..

Spring 2023.04.20

Spring AOP 3편 (With Spring 트랜잭션)

개요 2편에서는 Spring AOP의 적용방법에 대해서 알아보았다. 3편에서는 Spring AOP의 적용사례중 가장 많이 사용되는 스프링 트랜잭션(@Transactional)의 동작 방식을 알아보도록 하자. Spring 트랜잭션 프록시 동작 과정 이전편에서 프록시, 어드바이스, 포인트컷, 어드바이저 에 대해서 알아보았다. Spring 트랜잭션도 AOP 기반으로 동작하기 때문에 위 4가지 요소를 집고 넘어가야한다. 프록시 (in Spring 트랜잭션) @Transactional 애노테이션이 클래스나 메소드에 붙어있으면, 트랜잭션 AOP는 해당 클래스를 프록시로 만들어서 스프링컨테이너에 등록한다. 이전편에서 AnnotationAwareAspectJAutoProxyCreator라는 빈 후처리기가 포인트 컷을 ..

Spring 2023.04.20

Spring AOP 2편 (With Spring Transaction)

개요 1편에서 프록시, 어드바이스, 포인트컷, 어드바이저의 개념을 알아보았다. 이번 편에서는 이러한 4가지 요소를 활용하여 Spring AOP가 어떻게 적용되는지 살펴보도록 하자. Spring AOP 적용방법 위에서 프록시, Advice, Advisor, 포인트컷에 대한 개념을 정리해 보았다. Spring AOP 적용방법에 대해서 알아보자. 아래와 같이 4가지 방법으로 Spring AOP를 적용할 수 있다. (아래로 갈수록 좋다.) 프록시객체 직접 구현 빈 후처리기 사용 AnnotationAwareAspectJAutoProxyCreator 사용 @Aspect 사용 실무에서는 거의 4번 사용한다. 그렇기 때문에 AOP 동작과정을 모르고 넘어가는 경우가 많다. @Slf4j public class Sample..

Spring 2023.04.20

Spring AOP 1편 (With Spring Transaction)

개요 나는 Spring AOP를 사용해서 어려가지 기능을 구현했다. 하지만, Spring AOP의 정확한 동작원리에 대해서 알지는 못했다. 그래서 이번기회에 Spring AOP의 꽃이라고 불리는 Spring Transaction(@Transactional) 코드를 예시로 분석해보면서 Spring AOP 에 대해서 공부해 보려고 한다. Spring AOP Spring Transaction 코드를 보기전에 먼저, Spring AOP 에 대해서 개념을 정리해보자. 위의 그림을 보면, 프록시가 여러개의 어드바이저를 가지고 있고, 어드바이저는 1개의 포인트컷과 하나의 어드바이스를 가지고 있다. 또한, 프록시는 Target도 가지고 있으며, Target의 메소드 하나하나가 조인포인트가 될 수 있다. 포인트컷은 여러..

Spring 2023.04.20

SpringMVC를 이용해서 요청 Body값 Trim처리하기

개요 우리가 개발한 프레임워크를 사용하는 팀이 @RequestBody를 통해 전달되는 데이터에 대해 trim 처리를 요청했다. 이 기능을 구현하면서 예전에 공부한 SpringMVC의 코드를 복습할 수 있어 좋았다. 그래서, 제가 공부한 내용을 간단하게 정리하려고 합니다. SpringMVC의 요청 처리 흐름 Trim 처리를 위해 SpringMVC를 사용하려면 먼저 SpringMVC가 요청을 어떻게 처리하는지 이해해야 한다. 이해를 돕기 위해 아래의 클래스들을 살펴보자. 위의 그림과 같이, 먼저 DispatcherServlet이 요청을 받아서 doDispatch() 메소드에서 HandlerMapping을 하고, 그 결과에 따라서 HandlerAdapter를 찾는다. HandlerAdapter를 보면, sup..

Spring 2023.03.06

AbstractRoutingDataSource를 통한 Multi-DataSource 구현

개요 사용자 로그인 정보에 따라 다른 DB를 참조하고자 하는 요구사항이 있었다. 지금까지는 yml에 설정된 DataSource 정보가 빈으로 등록되는, 즉 정적인 방식으로 DataSource를 빈으로 주입하였다. 조사를 진행하던 중, AbstractRoutingDataSource를 사용하여 동적으로 DataSource를 결정하는 방법이 있다는 것을 알게 되었다. 구현 내용을 정리하기 앞서 먼저 DataSource가 어떤 것인지 간단히 정리해보자. DataSource DataSource의 역할은 간단하다. 바로 Connection을 관리해 주는 빈이다. 보통은 아래와 같이 yml에 datasource 정보를 입력하면, Spring Boot가 자동으로 DataSource를 빈으로 등록해 준다. 참고로 Spr..

Spring 2023.02.04

JDK 동적 프록시

개요 프록시를 사용해서 기존의 코드를 건드리지 않고, 새로운 기능을 추가할 수 있다. 하지만 프록시를 적용하고 싶은 대상의 숫자 만큼 프록시 클래스를 만들어야 한다는 단점이 있다. 이러한 문제를 해결하는 방법이 바로 동적 프록시이다. 그리고 동적프록시를 만드는 방법중 하나인 JDK 동적 프록시를 구현하는 방법을 알아보려고 한다. 코드 예시 먼저 아래와 같이 2개의 인터페이스와 구현체를 구현한다. 프록시를 적용하고 싶은 대상이 된다. public interface AInterface { String call(); } @Slf4j public class AImpl implements AInterface { @Override public String call() { log.info("A 호출"); return..

Spring 2022.08.06

ApplicationEventPublisher

ApplicationEventPublisher 란? ApplicationEventPublisher는 ApplicationContext가 상속하는 인터페이스 중 하나이다. ApplicationContext에는 ApplicationEventPublisher 인터페이스가 이미 구현되어있다. 그렇기 때문에 ApplicationEventPublisher를 이용해서 쉽게 이벤트를 발생시키고 처리할 수 있다. Design Pattern 중 하나인 옵저버 패턴의 구현체이다. 또한, Event를 발행해서 중첩되는 Transactional 내부에서 Commit 시점을 핸들링 할 수도 있다. 이벤트 처리 구조 먼저 이벤트를 정의한다. Publisher 를 통해서 이벤트를 발생시킨다. Listener 를 통해서 이벤트를 이벤..

Spring 2022.06.11

MapStruct

MapStruct Layer 간의 객체 변환 로직은 개발자가 직접 구현해도 되지만, 반복적이고 불필요한 코드가 많아지고, 단순한 실수로 인한 개발 생산성이 떨어지게 된다. 이를 위해 많이 사용하는 매핑 라이브러리로 ModelMapper 가 있는데, MapStruct 를 사용하면 ModelMapper 와 비교해서 몇몇 장점을 가지고 있다. MapStruct vs ModelMapper ModelMapper 는 리플렉션 기반으로 동작하여 실제 매핑 로직을 쉽게 파악하기 어렵다. MapStruct 는 코드 생성 방식으로 동작하기 때문에 생성된 코드를 통해 로직을 쉽게 파악할 수 있다. 생성된 코드를 눈으로 보며 디버깅이 가능해서 로직 분석도 가능하고 수정도 가능하다. MapStruct 는 컴파일 타임에 매핑 오..

Spring 2022.04.09

Handler Methods

@RequestMapping @RequestMapping( name = "nameForView", // 뷰 템플릿에서 찾는 이름 value = "/places", // URI 경로 path = "/places", // URI 경로 method = RequestMethod.GET, // Get 방식 params = "test=true", // test=true 파라미터 있는 요청 headers = "header-auth=stupidPassword", // header-auth 헤더값 있는 요청 consumes = MediaType.APPLICATION_JSON_VALUE, // json 으로 데이터 주는 요청 produces = MediaType.APPLICATION_JSON_VALUE // json 데이..

Spring 2022.04.09