스프링의 Task Executor 설정을 특별히 건드리지 않았더니 요청이 몰려드는 시점에 @Async를 붙인 메서드들의 처리가 느려지는 것을 확인했다. 서버 설정을 수정하는 김에 Task Executor 관련 주요 개념과 설정을 정리하려 한다. Task Executor 스프링 어플리케이션에서 @EnableAsync 설정을 추가하고 @Async가 붙은 메서드를 런타임에 호출 시 Runnable 혹은 Callable의 형태로 스레드 풀의 Blocking Queue에 작업을 등록한 뒤 비동기로 처리된다. 비동기 처리 시 작업을 등록할 스레드 풀이 필요한데, 스프링 부트가 아닌 순수 스프링 환경에서는 별도의 설정이 없다면 AsyncExecutionInterceptor에 의해 요청마다 스레드를 새로 생성하는 ..
최근 ORM 없이 순수 JDBC + Spring, 그리고 JDBC template을 통한 SQL mapper + Spring 조합의 웹앱들을 만들어보았다. Presentation, Service, Persistence 세 레이어를 ATDD 스타일로 구현하며 단위 테스트와 통합 테스트를 다양하게 작성해보았고, 괜찮았던 방법과 고민했던 포인트들을 적어보려고 한다. 각 레이어에 대한 단위 테스트는 Mockito를 통한 Slice 테스트로 Out - In 방식의 TDD에 용이한 Mockito Persistence -> Service -> Presentation 순서로의 In-Out 방식의 개발을 진행하면 상위 레이어를 구현할 때 하위 레이어가 이미 모두 구현되있으므로 하위 레이어를 포함한 단위 테스트를 구현할 ..
스프링의 컨트롤러 메서드는 크게 데이터를 반환하는 RestController와 뷰를 반환하는 일반적인 Controller로 나뉜다. RestController의 반환 값은 HttpMessageConverter에 의해 json과 같은 형식으로 변환되어 전달되고, Controller의 반환 값은 뷰의 이름으로 간주되어 ViewResolver가 서버 내의 적절한 뷰 파일을 찾아 처리한다. 초기화 ViewResolver를 호출하고 사용하는 클래스는 DispatcherServlet이므로, DispatcherServlet에 대해 간단히 알아야 한다. ApplicationContext가 초기화된 후에 DispatcherServlet 또한 초기화되는데, 이때 사용될 ViewResolver를 모두 찾아 리스트로 가져온다..
Interceptor에서 로그 생성, yml 파일로 별도 저장 설정하기 스프링에서 요청과 응답이 어떻게 처리되었는지 간단하게 기록을 남기고 싶었다. AOP를 사용할 수도 있지만 나는 Interceptor의 preHandle()과 postHandle()를 통해 로그를 남기는 방법을 선택했다. 아래와 같이 interceptor를 만들고 @Configuration이 붙은 파일에서 Interceptor를 추가하였다. public class LoggingInterceptor implements HandlerInterceptor { private final Logger logger = LoggerFactory.getLogger(this.getClass().getSimpleName()); @Override publi..
스프링에서 사용자의 요청은 필터를 거쳐 DispatcherServlet으로 넘어가고, 내부의 doDispatch() 메서드를 통해 해당 요청에 대한 인터셉터들의 preHandle()이 처리된 후 컨트롤러로 넘어간다. 나의 경우 인터셉터에서 인증 관련 처리를 하기 위해 Authentication 헤더를 읽어 인증과 인가를 수행한다. 이후 ArgumentResolver 혹은 컨트롤러에서 다시 사용자의 이메일 혹은 아이디를 통한 처리를 진행한다. 이때 인터셉터에서 이미 암호화된 Authentication 헤더의 값을 해석하고 파싱 했음에도 값을 캐싱하지 않는다면 이후의 ArgumentResolver에서 다시 해석과 파싱 작업을 해야 한다. 이런 불편을 없애기 위해 컨트롤러 메서드 앞에서 요청이 처리될 때 값을..
DispatcherServlet과 그 내부를 살펴보며 어떤 순서로 요청이 처리되는지, 그리고 어디서 어떻게 최적의 핸들러를 탐색하는지 알아보았다. 내부 구현은 Spring의 버전에 따라 달라지므로 세부 코드보다는 클래스 간 흐름이 어떤 식으로 이루어지는지 보는 것을 추천한다. 설명에 사용된 Spring 버전은 6.0.7이다. DispatcherServlet의 처리 순서 DispatcherServlet 은 우리가 만들어놓은 Handler(컨트롤러), Interceptor, 에 대한 정보를 리스트의 형태로 가지고 있다. ApplicationContext가 완성된 뒤 HandlerMapping 등 각 단계에 필요한 빈 타입을 순차적으로 찾아 등록한다. // org.springframework.web.servl..
- Total
- Today
- Yesterday
- thenComparing
- Java
- 우테코 5기
- Spring
- java switch case
- springboottest
- GitHub Discussion Template
- stubbing
- logback-spring.xml
- 함수형 인터페이스
- JPA
- 스프링
- GitHub Discussion
- GitHub Discussion 템플릿
- 람다식
- 자바
- 의존성 주입
- Payload 암호화
- 우테코 프리코스
- JPA JSON
- Fromtail
- Spring Boot Monitoring
- 생성자 주입
- RandomPort
- 우테코
- Spring 테스트
- invokedynamic
- MySQL
- MySQL 이벤트 스케줄
- Jenkins 예약 배포
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |