728x90
반응형

Dev./Spring 18

[Spring] QueryDSL Projection 방식 비교

개요QueryDSL로 검색 API를 구현하면서 엔티티가 아닌 검색 전용 DTO로 결과를 조회해야 했다.DTO 매핑방식으로 두가지 선택지가 있다는 것을 알게되었다Projections.constructor()@QueryProjection두 방식은 결과는 같아 보이지만,안전성 · 유지보수성 · 오류 발견 시점에서 큰 차이가 있었다. Projections.constructor 방식.select(Projections.constructor( TodoSearchResponse.class, todo.title, manager.id.countDistinct(), comment.id.countDistinct()))특징DTO에 QueryDSL 의존성 X생성자만 있으면 바로 사용 가능설정이 간단단점 생성..

Dev./Spring 2025.12.17

[Spring] Spring Security + JWT로 로그인 기능 구현

전체적인 흐름 클라이언트가 /auth/login 으로 이메일/비밀번호 전송서버에서 사용자 검증 후 JWT 발급이후 요청들은 Authorization: Bearer token헤더에 JWT를 담아서 호출커스텀 JwtAuthFilter가 토큰을 검증하고 userId를 꺼냄@AuthUser 파라미터로 컨트롤러에 userId를 바로 주입→ 컨트롤러/서비스는 JWT 구조를 모른 채 로그인된 사용자 ID만 다룸설계JwtUtil - JWT 생성 및 검증역할토큰 생성토큰 검증Claims / subject 추출설계 기준subject에는 userId를 넣음 (주 식별자)claim으로 email 정도만 추가validate()는 예외 캐치로 단순 처리@Componentpublic class JwtUtil { @Value(..

Dev./Spring 2025.12.09

[Spring] Transactional 사용시 자가호출(Self-Invocation)이슈

문제다음과 같은 코드에서,한 메서드 안에서 다른 @Transactional 메서드를 호출하면나는 REQUIRES_NEW가 적용되어 별도 트랜잭션이 만들어질 것이라고 기대했다.그러나 실제 동작은 전혀 달랐다.@Service@Slf4j@RequiredArgsConstructorpublic class OrderService { private final StockService stockService; private final PaymentService paymentService; private final PaymentRepository paymentRepository; private final OrderRecordService orderRecordService; @Transaction..

Dev./Spring 2025.12.08

[Spring]왜 Security 의존성을 추가하면 API 호출시 401이 뜰까

기존에 잘 돌아가던 demo 프로젝트에 Security 의존성을 추가하니 모든 API 호출시 401에러가 떴다. 왜 의존성 추가 하나만으로 잘 돌아가던 서버가 에러를 뱉는걸까?Security의 기본 보안 정책 자동 활성화Spring Security는 의존성 추가만으로도 다음 설정을 자동 적용 모든 요청은 인증 필요인증되지 않은 요청은 → 401 UnauthorizedForm 로그인 페이지가 자동 생성됨기본 사용자 계정이 자동 생성됨 (username=user, password=콘솔에 출력)즉 security가 추가되며 모든 요청을 가로막은 것이다.Security를 추가한 후의 동작 흐름왜 401일까?Spring Security가 요청을 Controller로 보내기 전에 차단하기 때문 , 컨트롤러에 도달하..

Dev./Spring 2025.12.06

[Spring] AOP 정리

AOP란AOP (Aspect Oriented Programming) 는 여러 곳에 반복되는 공통 관심사를 비즈니스 로직과 분리해서 한 곳에서 관리하기 위한 프로그래밍 기법AOP가 왜 필요할까?예를들어 기획자가 개발자님 성능 측정을 위해 모든 메서드에 시작 시간과 종료 시간을 남기는 기능 추가해주세요라고 요청을 했을 때public void save() { log.info("start"); // 비즈니스 로직 log.info("end");}다음과 같은 코드가 모든 서비스 메서드마다 중복되면 로깅, 트랜잭션, 권한 체크 코드가 모든 메서드에 흩어짐수정하려면 전체 코드를 다 건드려야 함비즈니스 로직이 더러워짐AOP 도입 후에는 시간 측정은 AOP가 알아서 처리한다.AOP는 어디에 적용되는걸까?..

Dev./Spring 2025.12.03

[Spring] Interceptor 정리

Interceptor란Spring MVC에서 컨트롤러(Controller) 호출 전·후에 요청을 가로채서 공통 로직을 수행하는 도구JWT 기반 인증이 끝난 후, 인증된 사용자 정보(SecurityContext)를 활용해자원 소유자 검증역할 기반 접근 제어API 사용 제한등의 부가 검증 수행Spring MVC 요청 흐름[사용자 요청] ↓[JwtFilter] ↓[SecurityContextHolder에 인증 저장] ↓[Interceptor] ↓[인증 사용자 검증] ↓[Controller]Interceptor가 왜 필요할까?예를 들어 컨트롤러 마다 다음과 같은 코드가 반복된다면if (!isLogin(request)) { throw new UnauthorizedException(..

Dev./Spring 2025.12.02

[Spring] interface의 default 메서드를 언제 써야 할까

default 메서드란설계 확장을 위한 도구Java 8 이전에는 인터페이스에 추상 메서드만 선언할 수 있었다. 문제는 인터페이스를 이미 여러 구현체가 구현하고 있는 상황에서 메서드 하나를 추가하면 모든 구현체가 깨짐이문제를 해결하기 위해 default 메서드가 나왔다public interface Repository { Optional findById(Long id); default T getOrNull(Long id) { return findById(id).orElse(null); }} 인터페이스에 기본 구현을 제공기존 구현체를 깨지 않고 기능 추가 가능무엇을 담당하는 메서드일까?모든 구현체에서 동일하게 동작해야 하는 공통 행위구현체마다 바뀌면 안되는 로직맥락을 몰라도 실행 ..

Dev./Spring 2025.11.29

[Spring] 스프링이 싱글톤 빈을 생성하는 과정

싱글톤이란?객체 하나만 만들어 전역적으로 공유하는 패턴핵심단 하나의 인스턴스어디서든 같은 인스턴스를 공유싱글톤 빈스프링은 기본적으로 애플리케이션 당 하나의 객체만 만들어 재사용싱글톤 스코프 제공개발자가 별도로 prototype/request/session scope 바꾸지 않는 한 1개의 객체만 생성후 재사용생성 과정1. 컴포넌트 스캔스프링이 실행되면 @ComponentScan 설정에 따라 프로젝트를 훑어 빈 클래스들을 찾는다.ex)@Component@Service@Repository@Controller@RestController이 클래스를 빈으로 만들겟다고 등록2. 빈 객체를 한번만 new 로 생성이때 싱글톤 인스턴스가 생성된다.스프링은 내부적으로 싱글톤 저장소를 Map 형태로 사용하고 있다.singl..

Dev./Spring 2025.11.21

[Spring] Lombok 생성자 @NoArgsConstructor, @AllArgsConstructor, @RequiredArgsConstructor

@NoArgsConstructor매개변수가 없는 기본 생성자를 자동으로 만들어준다 new User()@NoArgsConstructorpublic class User { private String username; private int age;}언제 사용할까JPA Entity 필수 조건 - Hibernate가 리플렉션으로 객체를 생성하기 때문에 protected 기본 생성자가 필요함DTO 중에서도 빈 객체 만들고 setter로 채우는 경우⚠️ 주의점모든 필드가 초기화되지 않은 상태로 생성되므로 불완전한 객체가 생긴다.엔티티는 protected로 제한하는 게 안전함.@AllArgsConstructor모든 필드를 매개변수로 받는 생성자를 만들어준다 new User( "Kim", 25 )@AllArg..

Dev./Spring 2025.11.20

[Spring] 응답DTO에 엔티티 의존성을 주입해야 하는 경우

Response DTO란도메인 엔티티를 외부에 그대로 노출하지 않고 프론트에서 필요한 형태로 변환해 전달하는 역할즉, Response DTO는 도메인의 상태를 읽기 전용으로 표현하는 포장지다.그렇기 때문에 엔티티를 주입 DTO 안에서 필요한 정보만 꺼내 포맷팅하는 방식이 자연스럽다.주입 해야 하는 경우 - 필드 수처음에 Response DTO 만들 때 필드를 직접 하나씩 넣는 방식을 택했다.return new UpdateCommentResponse( comment.getId(), comment.getUser().getUsername(), comment.getSchedule().getTitle(), comment.getContent(), comment.getModifiedAt()..

Dev./Spring 2025.11.19
728x90
반응형