java

    [Spring] Service - 인터페이스 도입과 버저닝

    [Spring] Service - 인터페이스 도입과 버저닝

    예전에 프로젝트를 하다 보면 Controller가 Service 구체 클래스를 의존하는 방식을 많이 사용했었는데, 이러한 설계 방식은 Controller가 Service 클래스 단 하나만 의존하기 때문에 다형성이 부족하다. 따라서 객체 지향 설계(DIP)와 향후 다음 버전에 대한 확장성을 위해 Service 계층에 인터페이스를 도입했다. 기존 설계 방식 @RestController @RequiredArgsConstructor public class Controller { private final Service service; // 클래스 직접 주입 } @Service @RequiredArgsConstructor public class Service { private final Repository repo..

    [Spring] 의존성 역정 원리(DIP) 관련 용어

    예전에 어떤 시니어 분이 공유해준 글(참고자료)을 나에게 맞게 쉽게 정리해봤다. 평소 겉으로 알고 있던 개념이지만, 이번 기회에 조금 더 명확히 이해할 수 있었다. IoC(Inversion of Control, 제어 역전) 전통적인 방식에 반대되는 흐름으로 코드가 진행되는 것을 말하는 일반적인 용어이다. IoC를 설명하는 단골 예시는 바로 라이브러리와 프레임워크이다. 라이브러리는 내 코드가 라이브러리 코드(외부 코드)를 호출하지만, 프레임워크는 프레임워크(외부 코드)가 내 코드를 호출한다. → IoC는 프레임워크의 일반적인 특성이다. Dependency Inversion Principle(DIP, 의존성 역전 원리) 의존관계를 갖는 인스턴스의 구성이 추상화에 의존하는 것을 뜻한다. 다음과 같이 인스턴스 ..

    [Spring] @TransactionalEventListener에서 예외가 발생하지 않는 이슈

    문제 @TransactionalEventListener에서 예외가 발생하지 않는 이슈 이게 무슨말인가 하면, @TransactionalEventListener에서 예외 발생 시, 예외를 찍어주지 않는다. 처음엔 예외 자체가 발생하지 않았다고 생각했는데, 로그를 debug로 찍어보면 잘 나온다. 즉, 예외는 발생했지만 해당 예외가 error가 아닌 debug로 찍힌다는 것. 원인 콜스택을 분석해봤다. @Transactional이 붙은 메서드를 본 메서드, @TransactionalEventListener를 이벤트 메서드라고 했을 때, 이벤트 메서드는 본 메서드의 트랜잭션이 커밋된 이후, 실행하는 메서드다. 이 때 이벤트 메서드는 실행 후 종료 직전 TransactionSynchronization.after..

    [Spring] 스프링 디렉터리 패키지 구조

    계층형 디렉터리 구조 com ㄴ example ㄴ nuribank ㄴ config ㄴ controller ㄴ domain ㄴ repository ㄴ service ㄴ security ㄴ exception 스프링 각 웹 계층들을 대표하는 클래스, 디렉터리들을 기반으로 패키징한다. 스프링 웹 계층 Web Layer: 사용자의 요청과 이에 대한 응답 반환의 전반적인 처리가 일어나는 영역 Service Layer: Web Layer와 Repository Layer 사이에서 실질적인 애플리케이션 비즈니스 로직이 일어나는 영역 Repository Layer: DB에 접근 및 통신하는 영역 장점 전체적인 구조를 빠르게 파악할 수 있다. 단점 각 패키지에 클래스들이 너무 많이 모이게 된다. 하나의 패키지 안에 서로 의..

    [Spring] Spring Data JPA의 페이징

    인자 타입 - Pageable findAll()과 같이 컬렉션 조회를 하게 되면 페이징이 필요할 때가 있다. 페이징을 위해서는 기본적으로 몇 번째 페이지인지에 대한 정보와(page) 한 페이지당 보여줄 데이터의 개수가(size) 필요하다. Spring Data JPA는 이러한 정보를 위해 Pageable 인터페이스를 사용한다. @GetMapping public ResponseEntity page(@RequestParam int page, @RequestParam int size) { Pageable pageable = PageRequest.of(page, size); Page members = memberRepository.findAll(pageable); return new ResponseEntity(..

    [Spring] @ControllerAdvice, 특정 예외 발생 시 404에러가 발생하는 이슈

    문제 서버에서 IllegalArgumentException 등의 여러 예외는 미리 설정한 @ControllerAdvice를 지나게 되는데, 분명 ExceptionHandler에서 특정 예외에 대해 400, 403 에러 등의 status code를 지정했지만 전부 404 에러로 바뀌어서 리턴된다. @ControllerAdvice class CherryAdminGlobalExceptionHandler { @ResponseStatus(HttpStatus.BAD_REQUEST) // -> 400코드 @ExceptionHandler(IllegalArgumentException::class) fun handle(ex: IllegalArgumentException): Response { log.error("{}", ..

    [Spring] Spring AOP와 실무 응용

    AOP AOP(Aspect Oriented Programming): 관점 지향 프로그래밍 관심사의 분리를 허용함으로써 모듈성을 증가시키는 것이 목적인 프로그래밍 패러다임이다. Spring AOP Spring에서도 AOP를 지원하며, 공통적으로 처리해야할 부분은 따로 모듈화해서 개발자가 비즈니스 로직에만 집중할 수 있도록 해준다. 예를 들어, 어떤 API의 어느 지점(Pointcut)에서 어떤 작업을 수행할 것인지(Advice)를 공통적으로 처리할 수 있다. 다음 예시를 보자. (본 코드는 Kotlin을 기준으로 작성되었다) Pointcut "어느 지점에서" @Aspect class PointcutList { @Pointcut("execution(* com.example.ltaop..controller....

    [Spring] PostgreSQL - PostGIS, JPA를 통해 공간 데이터 다루기

    [Spring] PostgreSQL - PostGIS, JPA를 통해 공간 데이터 다루기

    데이터베이스에 숫자, 문자열이 아닌 점, 선, 면 등의 정보를 담아야 할 때, 주로 공간 데이터를 사용한다. 본 포스팅에서는 Spring + JPA 환경에서 PostgreSQL의 extension인 PostGIS를 통해 공간 데이터를 다루는 방법을 알아보겠다. PostGIS의 도입 배경과 설치 과정은 아래 글을 참고하자. 2023.01.11 - [database] - [Postgresql] PostGIS 설치 - MySQL이 아닌 PostgreSQL을 사용하는 이유 [Postgresql] PostGIS 설치 - MySQL이 아닌 PostgreSQL을 사용하는 이유 배경 프로젝트 도중 공간 데이터를 다룰 일이 있었다. 나는 주로 MySQL을 사용하기 때문에 처음에는 MySQL이 지원하는 공간 데이터 타입(..