여러 서비스에서의 Message기반 비동기 호출 아키텍처를 구성할 때, Message Driven Architecture, Event Driven Architecture의 선택지가 존재한다. 여기서 Message와 Event의 차이를 정리해보려 한다. 메시징 메시징은 서비스가 메시지를 서로 비동기적(메시지 브로커를 사용하는 경우와 통상적인 경우)으로 주고받는 통신 방식이다. 보통 메시징 기반 애플리케이션은 서비스 사이에 Message Brocker(대표적으로 Kafka, RebbitMQ)를 두어 비동기 통신을 구현하지만, 서비스가 직접 서로 통신하는 BrockerLess 아키텍처도 존재한다. BrockerLess 아키텍처는 통신할 애플리케이션이 가용중이 아니라면 내부적으로 큐를 두는 방식 등을 통해 메시..
분류 전체보기
Spring 기반 애플리케이션에서 예외를 핸들링하는 전략들에 대해 알아보고자 한다. Servlet 기반 예외 처리 서블릿 기반 예외 처리는 발생한 예외를 WAS(Tomcat) 까지 전달한다. 그 이후 매핑된 예외 종류에 따라 Dispatcher Servlet에 다시 요청하며 예외를 핸들링한다. (forward와 비슷한 개념) @Component public class WebServerCustomizer implements WebServerFactoryCustomizer { @Override public void customize(ConfigurableWebServerFactory factory) { List errorPages = List.of( new ErrorPage(HttpStatus.NOT_FOU..
Spring Interceptor와 Servlet Filter 모두 공통 관심사항을 처리할 수 있는 유용한 기능이다. 예를 들어 로그인이 꼭 필요한 서비스에서 로그인 여부를 체크하는 작업이 필요하다고 할 때, 각 컨트롤러에서 보일러 플레이트 코드를 반복해서 작성해야 한다는 불편한 점이 존재한다. 이러한 횡단 관심사(cross-cutting concern)는 스프링에서 지원하는 AOP를 사용하여 해결할 수도 있지만 웹과 관련된 공통 관심사는 HTTP header 정보, URL 정보등이 필요한 경우가 많기에 이를 지원하는 서블릿 필터 혹은 스프링 인터셉터를 사용하는 것이 좋다. 서블릿 필터와 스프링 인터셉터는 HttpServletRequest를 포함한 여러 부가 기능을 지원하기에 특정 URL을 블랙 리스트 ..
SLF4J 개발을 진행하며 로그를 기록하고 trace하기 위해 로그 라이브러리를 사용한다. 스프링에서는 기본 로그 라이브러리로 Logback을 지원하고 이를 SLF4J 인터페이스를 통해 사용할 수 있다. SLF4J를 사용하기 위해서는 아래와 같은 로거 선언 방식 중 하나를 선택하여 사용하면 된다. @Slf4j // 클래스 레벨에 해당 어노테이션 선언, 롬복 사용시 가능 public class TempClass { } private Logger log = LoggerFactory.getLogger(getClass()); private static final Logger log = LoggerFactory.getLogger(Xxx.class); 시스템 콘솔 출력 함수로 로그를 남기면 안되는 이유 Java에서..
이번 프로젝트는 멀티 모듈환경에서 헥사고날 아키텍처를 적용하여 구성해 보았다. 모듈과 클래스의 의존성 방향 다이어그램은 아래와 같다. 이처럼 헥사고날 아키텍처로 프로젝트를 구성해보니 MVC 아키텍처와 비교했을 때, 장단점이 확실하게 보였다. 장점은 비즈니스 로직, 도메인이 UI, Infra(세부사항)를 모른다는 것과 세부사항이 비즈니스 로직의 플러그인이 된다는 것이다. 이는 세부사항이 결정되지 않은 시점에도 비즈니스 핵심 로직을 구현할 수 있다. 세부사항이 자주 변경되거나 아직 결정되지 않은 시점에 헥사고날 아키텍처를 도입하면 생산성이 증가할 것이라고 생각한다. 하지만 단점또한 명확하다. 아직 헥사고날 아키텍처의 디렉터리 구조에 익숙하지 않다는 점을 감안하더라도 패키지 구조가 복잡하다. MVC 아키텍처와..
도서를 읽으며 의존성이 무엇인지 명확하게 파악할 수 있었다. 의존성을 이해함으로써 지금까지 학습했던 SOLID 원칙, 스프링프레임워크의 IoC/DI의 편리함, 객체지향의 다형성 나아가 객체지향의 장점까지 되돌아 볼 수 있는 좋은 기회였다. 클린 아키텍처를 읽고 나에게 주입된 문장은 ‘정책과 세부 사항을 분리하고, 의존 방향을 제어 흐름과 반대로 역전시켜 세부사항이 정책을 의존하게 하라’이다. 이 문장은 클래스 레벨부터, 모듈과 컴포넌트, 서비스, 시스템 레벨까지 아우르는 말이라고 생각한다. 상위 수준의 정책은 인터페이스를 두어 하위 수준의 세부 사항 컴파일 타임에는 의존하지 않고, 런타임에 의존한다. 또한, 세부 사항은 정책의 인터페이스를 구현하도록 하여 확장에 열려있고, 세부 사항의 변경에 정책은 영향..
스프링 부트 멀티모듈을 환경에서 발생했던 Boot Jar 설정 오류를 다뤄보고자 한다. root 디렉터리의 주석 부분을 추가하여 문제를 해결할 수 있었다. 오류 발생 시점의 build.gradle 파일은 아래와 같다. subprojects { apply plugin: 'java' apply plugin: 'org.springframework.boot' apply plugin: 'io.spring.dependency-management' dependencies { compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' } tasks.named('test') { useJUnitPlatform() } // boo..
문제 JAVA 17, Spring Boot 3.2 멀티 모듈 구조에서 각 모듈간의 의존성을 제대로 선언해놓고 실행했음에도 모듈에서 다른 모듈의 소스 정보를 못 읽어오는 이슈가 발생했다. 해당 문제를 해결하기 위해 애플리케이션 실행 지점에 다른 모듈의 객체를 생성하는 간단한 코드를 넣어 확인해보았다. 소스코드와 IDE 상에는 분명히 domain 모듈의 Product 클래스가 import 되어 있는데, 컴파일러가 Product 클래스를 import 하는 시점에 오류가 발생한다. 해당 프로젝트는 내가 예전에 작성하고 테스트까지 끝마쳤던 소스코드를 그대로 가져와서 동일한 환경으로 재구성 한 것이라 완벽하게 동일한 소스코드와 의존성을 가지고 있다. 이전의 프로젝트는 오류없이 정상적으로 실행되니 참 답답한 상황이 ..
🥕 이번 당근 클론 프로젝트에서는 기존에 자주 사용하던 MVC 구조가 아닌 헥사고날 아키텍처를 적용해보려 한다. 따라서 먼저 배경 지식을 습득후 간단한 예제 코드를 통해 헥사고날 아키텍처에 대해 익숙해지려 한다. 이전 포스팅과 이어집니다. MVC 구조에서 헥사고날 아키텍처로 🥕 이번 당근 클론 프로젝트에서는 기존에 자주 사용하던 MVC 구조가 아닌 헥사고날 아키텍처를 적용해보려 한다. 따라서 먼저 배경 지식을 습득후 간단한 예제 코드를 통해 헥사고날 아키텍처 hyunsb.tistory.com 이번에는 이전 포스팅에서 설명한 MVC 구조에서 싱글 모듈 헥사고날 아키텍처를 적용한 API 서버를 멀티 모듈로 마이그레이션 해보려 한다. 싱글 모듈의 한계점은 명확하게 존재한다. 모든 로직이 하나의 dependen..