목록Programing/Spring (73)
T_era
Mockito 어노테이션과 메서드 검증에 대한 정리1. Mockito 어노테이션@Mock가짜 객체를 생성하는 어노테이션실제 객체의 동작을 시뮬레이션할 수 있음모든 메서드가 기본값을 반환 (null, 0, false 등)주로 외부 의존성을 가진 객체를 테스트할 때 사용@MockUserRepository userRepository; // 가짜 객체 생성// 사용 예시when(userRepository.findById(1L)).thenReturn(Optional.of(user)); @InjectMocks생성된 가짜 객체를 주입받는 클래스에 사용@Mock으로 생성된 객체들을 자동으로 주입주로 테스트 대상 클래스에 사용@MockUserRepository userRepository;@InjectMocksUserS..
API를 로깅하기 위한 방법을 알아보면서 알게된 Interceptor와 AOP의 주요 사용처와 차이점을 찾아보게 되었다1. Interceptor정의:Spring MVC의 요청 처리 과정에서 특정 URL 패턴에 대해 요청을 가로채서 처리하는 컴포넌트HandlerInterceptor 인터페이스를 구현하여 사용주요 사용 시점:public class CustomInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { // 컨트롤러 실행 전 return true..
프로젝트 진행 중 연관관계 매핑된 엔티티를 조회할 때 N+1 문제가 발생하였다. User, Post, Comment, Like 테이블이 양방향 매핑으로 구성되어 있었는데, 특히 Comment 조회 시 작성자 정보(User)와 포스트의 정보(Post)를 같이 읽어오는 과정에서 Comment, Post, User를 각각 조회하는 추가 쿼리가 발생하는 문제가 발생하였다. 이는 FetchType.LAZY 설정으로 인해 발생하는 전형적인 N+1 문제에 해당한다.문제 발생 코드 예시아래 Comment 엔티티는 User 및 Post와 FetchType.LAZY로 연관되어 있다.@Getter@Entity@Table(name = "comments")public class Comment extends BaseEntity ..
좋아요 기능을 개발하면서 동시에 여러 사용자가 버튼을 누를 때 발생할 수 있는 동시성 문제에 대해 고민하게 되었다. 이는 여러 스레드나 프로세스가 공유 자원에 동시에 접근하여 예상치 못한 결과를 초래하는 현상을 말한다.동시성 문제의 종류와 좋아요 기능의 연관성동시성 문제는 여러 형태로 나타날 수 있다.경쟁 조건 (Race Condition): 여러 스레드가 동시에 공유 자원에 접근할 때, 자원의 최종 상태가 어떤 스레드가 마지막으로 접근했는지에 따라 달라지는 현상이다. 이는 예측 불가능한 결과를 초래한다.교착 상태 (Deadlock): 두 개 이상의 스레드가 서로 상대방이 점유하고 있는 자원을 기다리며 무한정 대기하는 상태를 말한다. 모든 스레드가 작업을 진행할 수 없게 되어 시스템이 멈추는 결과를 초래..
스프링 시큐리티는 복잡한 인증(Authentication) 및 인가(Authorization) 과정을 여러 컴포넌트를 통해 체계적으로 처리한다.클라이언트 요청: 사용자가 리소스 접근을 위해 요청을 보낸다.인증 객체 생성: 요청에서 **사용자 이름(username)**과 **비밀번호(password)**를 추출하여 Authentication 객체를 생성한다.AuthenticationManager를 통한 인증 수행:AuthenticationManager의 기본 구현체인 ProviderManager가 요청된 Authentication 객체를 처리할 적절한 AuthenticationProvider를 선택한다.AuthenticationProvider의 인증 로직 수행:선택된 AuthenticationProvide..
JPA를 사용하며 JpaRepository.save() 메서드가 특정 필드만 변경되었음에도 불구하고 UPDATE 쿼리가 전체 필드를 갱신하는 것처럼 보일 수 있다는 의문을 가지게 되었다. (정확히는 JPA의 변경 감지(Dirty Checking)는 기본적으로 변경된 필드만 갱신하지만, 특정 상황이나 구현체에 따라 전체 필드를 갱신하는 쿼리가 발생할 수도 있다.) 현재 프로젝트에서는 업데이트 요청이 적어 큰 문제가 없으나, 향후 성능 튜닝을 위해 QueryDSL 도입을 고려하게 되었다. 그런데 QueryDSL 적용 시 영속성 컨텍스트와 관련된 새로운 문제에 직면하게 되었다.오늘은 QueryDSL이 무엇인지 정리하고, 영속성 컨텍스트와 어떤 문제가 발생할 수 있는지 함께 살펴보겠다.QueryDSL이란?Que..
토큰과 세션을 통해 사용자 인증을 하는 기능을 구현했는데 URI마다 매번 인증코드를 넣는 것이 아쉬워서 어떤 방법이 있을지 찾아보다가 ArgumentResolver라는 기능을 알게 되었다. 이 ArgumentResolver가 어떤 동작을 해서 이 문제를 해결하는지 또 어떻게 적용시키는지 정리해보았다Spring의 ArgumentResolver는 요청 파라미터를 메소드의 인자로 변환하는 기능을 제공한다. 이는 HandlerMethodArgumentResolver 인터페이스를 구현하여 사용한다.ArgumentResolver의 역할요청 데이터 바인딩: 클라이언트로부터 전달된 HTTP 요청의 다양한 데이터(쿼리 파라미터, HTTP 바디, 헤더, 쿠키, 세션 등)를 컨트롤러 메소드의 특정 타입의 인자로 자동으로 변..
스프링에서 JPA를 사용할 때 엔티티 클래스에 적용되는 다양한 어노테이션들이 존재하며, 각각 특정 역할과 사용 이유를 갖는다. 주요 어노테이션들과 그 이유를 정리해보자1. @Entity사용 이유: 해당 클래스가 데이터베이스 테이블과 매핑되는 엔티티임을 명시한다. JPA는 이 어노테이션이 붙은 클래스의 인스턴스를 데이터베이스의 레코드와 연결하여 관리한다.2. @Table(name = "테이블_이름")사용 이유: 엔티티 클래스와 매핑될 데이터베이스 테이블의 이름을 지정한다. 클래스 이름과 테이블 이름이 다를 경우 명시적으로 테이블 이름을 설정해야 한다.3. @Id사용 이유: 해당 필드가 엔티티의 기본 키(Primary Key)임을 나타낸다. JPA는 @Id 어노테이션이 붙은 필드를 기준으로 엔티티를 식별하고..
jpa를 연습해보기 위해 사용하다 왜 상속받은 인터페이스에서 새로운 메서드를 정의만하고 구현을 하지 않았는데 작동하는지 의문이 들어 찾아보았다.public interface MemberRepository extends JpaRepository { Optional findByUserName(String userName);}위의 코드인데 나는 구현을 한적이 없다 Optional byUserName = memberRepository.findByUserName(userName);하지만 이 코드를 실행하면 재대로 반영이 된다 이유가 뭘까?JpaRepository 상속 인터페이스의 메서드 정의만으로 구현 없이 작동하는 이유는 Spring Data JPA의 Query Methods 기능에 기인한다. Spring..
Query Methods메서드 이름 기반 SQL 자동 생성 기능. JpaRepository는 기본 기능만 제공하며, 실제 개발에는 조건부 메서드 필요.코드 예시:public interface MemberRepository extends JpaRepository { Member findByNameAndAddress(String name, String address);}위 메서드는 다음과 같은 SQL로 자동 생성됨.SELECT * FROM member WHERE name = ? AND address = ?;JpaRepository 제네릭 타입의 Entity와 매핑되는 테이블의 SQL 생성. 개발자는 규칙에 따라 메서드 선언, SimpleJpaRepository에서 구현됨.해석 규칙:find...By....