Development/Diary 32

[Diary][Spring] Spring Webflux의 WebFilter는 자동으로 등록됩니다. (Security Filter Chain에 등록하면 발생할 수 있는 문제)

이 글에서는 WebFilter를 구현하면서 겪었던 잘못된 사용에 대해 다루고자 합니다.문제 상황Spring Cloud Gateway에 JWT 인증 필터를 구현하였다.위와 같이 @Value 값을 주입받기 위해, WebFilter를 구현하고 @Component 어노테이션을 붙여서 Bean에 등록했다.그리고 Security FilterChain에 구현한 Filter를 추가했다. 필터 우선순위도 넣어줬다.자연스러운 흐름이겠지만, 이것은 잘못된 사용이다. 왜냐하면, 디버그 모드로 찍어보면 필터를 두 번 검사하게 될 것이다.문제 원인https://docs.spring.io/spring-boot/reference/web/reactive.html#web.reactive.webflux.web-filters 문서를 참고해..

Development/Diary 2024.09.17

[Diary][Spring] N + 1 문제 해결을 위한 @EntityGraph를 사용할 때 주의할 점

N+1 문제 해결을 위해 적용하신 @EntityGraph의 경우, @EntityGraph를 설정할 때 필요 이상의 연관 엔티티들을 함께 로딩하게 되면 불필요한 데이터가 메모리에 적재되어 성능 저하를 유발할 수 있습니다.아래 글에서 N + 1 해결 방법으로 @EntityGraph를 사용하는 것을 선택했는데, 위와 같은 피드백을 받았습니다. [Diary] Spring ORM에서는 N + 1을 항상 신경쓰자. (tistory.com) [Diary] Spring ORM에서는 N + 1을 항상 신경쓰자.프로젝트를 진행하다가 드디어 N + 1을 마주치는 상황이 생겼습니다. 사실 이 문제가 정확히 언제 발생할 수 있는지 이해가 안 되었는데, 이렇게 쉽게 마주쳐서 기뻤습니다 후후문제 상황여기 장bezzang2.tist..

Development/Diary 2024.09.05

[Diary] Spring ORM에서는 N + 1을 항상 신경쓰자.

프로젝트를 진행하다가 드디어 N + 1을 마주치는 상황이 생겼습니다. 사실 이 문제가 정확히 언제 발생할 수 있는지 이해가 안 되었는데, 이렇게 쉽게 마주쳐서 기뻤습니다 후후문제 상황여기 장바구니 엔티티가 있다.장바구니는 User, Store, Product를 @ManyToOne으로 가지고 있다.여기서 FetchType을 명시하지 않았으므로, 자동으로 LAZY가 설정된다.아래는 이제 Response DTO를 만들기 위해서 만든 메서드이다.여기서 Cart와 연관된 Product, Store를 get 한다.이제 여기서 N + 1 문제가 발생한다. 대략 아래 log는, 위 메서드가 실행되면서 만들어지는 쿼리이다.2024-08-30T22:52:07.102+09:00 INFO 5292 --- [nio-8080-..

Development/Diary 2024.08.30

[Diary][Spring] Spring Security에서 Role과 Authority의 차이가 뭘까?

문제 상황위는 이미 해결한 PR인데, hasAnyRole을 사용하면 권한 체크가 안 되고, hasAnyAuthority를 사용해야 권한 체크가 잘 동작하는 일이 발생했다.문제 원인Spring Security 문서 26. Expression-Based Access Control (spring.io)  간단히 요약하면, 현재 principal에 명시된 roles 중에서hasRole([role])지정된 역할이 현재 사용자에게 있는 경우 true를 반환한다. 기본적으로 제공된 역할이 'ROLE_'로 시작하지 않으면, 'ROLE_'이 자동으로 추가된다. hasAuthority([authority])지정된 권한이 현재 사용자에게 있는 경우 true를 반환한다.하지만 UserRoleEnum 에서는 ROLE_을 붙이고..

Development/Diary 2024.08.29

[Diary][Spring] 식별,비식별 관계? 관계의 방향? 외래 키의 주인?

ERD를 설계하고, 엔티티 간에 관계를 매핑할 때 항상 헷갈리는 개념이 있습니다.일대다, 다대다 이런 관계는 알겠는데, 식별 관계로 할지, 비식별 관계로 할지, 그럼 엔티티 간에 관계는 양방향일지 단방향일지, 그럼 외래 키의 주인은 누구로 할지를 추가적으로 정해야 합니다.이 개념들이 혼동되지 않도록 다시 정리하고자 합니다.식별 관계와 비식별 관계식별 관계 (Identifying Relationship)식별 관계는 부모 테이블의 기본 키(Primary Key, PK)가 자식 테이블의 기본 키의 일부로 포함되는 관계이다.즉, 자식 테이블에서 부모 테이블의 기본 키가 자식 테이블의 기본 키에 포함되어, 두 테이블 간의 관계가 강하게 묶여 있다. 이 관계는 자식 테이블의 기본 키가 부모 테이블의 기본 키에 의존..

Development/Diary 2024.08.27

[Diary] @SpringBootApplication의 @ComponentScan 범위

문제 상황JwtUtil 클래스를 Bean에 등록했음에도, autowire을 할 수 없다는 경고가 자꾸 나온다.문제 원인: Component Scanning 범위원인이 무엇인지 갈피를 못 잡아서 GPT한테 물어보니, "Component Scanning이 이루어지는 패키지 안에 있음?"이라고 한다.경로를 다시 보니 개발이 이루어지는 domain과 global 디렉토리가 @SpringBootApplication 이 있는 패키지 밖에 있었다.문제 해결해결은 위 두 디렉토리를 패키지 안으로 넣어서 해결했긴 한데, 이 @SpringBootApplication의 Component Scan 범위에 대해 알게 되었다.기본적으로 Component Scan이 이루어지는 범위는 @SpringBootApplication이 적용..

Development/Diary 2024.08.26

[Diary][Spring] Spring Cloud Gateway와 FeignClient를 같이 사용하면 발생할 수 있는 문제

Spring Cloud Gateway는 비동기 방식의 요청 처리를 지원하는 API Gateway 입니다. 하지만 이와 같은 비동기 환경에서 동기식 HTTP 클라이언트를 사용할 경우 성능 저하나 예상치 못한 문제가 발생할 수 있습니다. 이번 글에서는 Spring Cloud Gateway에서 FeignClient를 사용할 때 발생할 수 있는 문제와 그 해결 방법에 대해 다루어 보겠습니다.문제 상황@Componentpublic class CheckUserRegisterFilter implements GlobalFilter { @Value("${service.jwt.secret-key}") private String secretKey; private final AuthClient authClie..

Development/Diary 2024.08.25

[Diary] AWS EC2에서 겪은 포트포워딩 문제: 리눅스 네트워크 인터페이스 eth0와 enX0

AWS EC2 인스턴스를 사용하여 웹 애플리케이션을 배포할 때, 퍼블릭 IPv4 DNS 주소를 통해 애플리케이션에 접속할 수 있습니다. 하지만 사용자는 종종 주소 끝에 애플리케이션이 동작하는 포트 번호를 추가해야 합니다. 이 문제를 해결하기 위해 포트포워딩을 설정하여 포트를 입력하지 않으면 자동으로 웹 서버 포트로 리디렉션 하도록 하려 했으나, 네트워크 인터페이스 이름을 잘 못 설정하여 동작하지 않았습니다. 이 글에서는 AWS EC2에서 포트포워딩 설정 중 발생한 문제와 그 해결 과정을 공유하고자 합니다.문제 상황 재현: EC2에 접속하여 포트포워딩 진행포트 번호를 입력하지 않아도 자동으로 접속되기 위해, 80포트로 오는 요청을 8080 포트로 전달하게 하는 포트포워딩 명령어를 다음과 같이 입력하였다.s..

Development/Diary 2024.08.01

[Diary] 지저분한 Service 메서드 코드 Command DesignPattern 적용기

이 글에서는 설문조사 웹 애플리케이션 개발 프로젝트에서 서비스 레이어 메서드의 로직이 가독성이 떨어지고, 유지보수가 어려운 상황을 개선하기 위해 Command 디자인 패턴을 적용한 경험을 공유하고자 합니다.Command 패턴Command 패턴은 행동 패턴 중 하나로, 요청을 객체의 형태로 캡슐화하여 여러 가지 다른 요청이 나중에 필요할 때 실행되거나 취소될 수 있도록 하는 패턴이다. 이 패턴을 사용하면 요청하는 객체와 요청을 수행하는 객체 사이의 결합을 느슨하게 만들 수 있다.Command 패턴의 핵심 아이디어는 작업을 요청하는 객체를 독립적으로 처리할 수 있게 하는 것이다.Command 패턴의 구성 요소Command 인터페이스:실행될 동작을 정의하는 인터페이스이다. 일반적으로 execute() 메서드를..

Development/Diary 2024.07.22