Backend 44

SecurityFilterChain

SecurityFilterChain Spring Security는 인증 처리 과정을 서블릿이 제공하는 필터를 기반으로 처리한다. Spring Security는 SecurityFilterChain을 제공하는데, 이는 인증과 인가를 위한 필터들의 모음이다. Spring Security에서는 인증, 인가에 대한 처리를 여러 개의 필터를 통해 연쇄적으로 실행하여 수행한다. 이때 상황에 따라 필요한 필터가 있고 필요 없는 필터가 있을텐데, 설정 클래스를 통해 필요한 필터들을 등록해주면 된다. 다음은 Spring Security 설정을 하는 설정 클래스의 예시이다. 이때 securityFilterChain 메소드는 SecurityFilterChain에 대한 전반적인 설정을 하고, SecurityFilterChain..

스프링의 트랜잭션 전파(REQUIRED, REQUIRES_NEW)

REQUIRED 옵션 [참고] 트랜잭션 전파 옵션 스프링은 다양한 트랜잭션 전파 옵션을 제공한다. 전파 옵션에 별도의 설정을 하지 않으면 REQUIRED가 기본으로 사용된다. 참고로 실무에서는 대부분 REQUIRED 옵션을 사용한다. 그리고 아주 가끔 REQUIRES_NEW을 사용하고, 나머지는 거의 사용하지 않는다. * REQUIRED: 가장 많이 사용하는 기본 설정이다. 기존 트랜잭션이 없으면 생성하고, 있으면 참여한다. * REQUIRES_NEW: 항상 새로운 트랜잭션을 생성한다. 기존 트랜잭션이 없으면 생성하고, 있어도 새로운 트랜잭션을 생성한다. 트랜잭션이 수행중이고 아직 끝나지 않았는데 또 다른 트랜잭션이 수행되면 어떻게 될까? 이때 처음 시작된 트랜잭션을 상대적으로 밖에 있기 때문에 외부 트..

Backend/Spring 2024.01.17

스프링의 트랜잭션 AOP(@Transactional)의 특징과 주의사항

트랜잭션 AOP 특징지난 글(https://olsohee.tistory.com/82)에서는 스프링이 트랜잭션을 제공하는 방식에 대해 알아봤다. 이번에는 스프링이 제공하는 트랜잭션 중 선언적 트랜잭션 관리 방식인 @Transactional에 대해 더 자세히 알아보자.@Transactional을 사용하면 스프링의 트랜잭션 AOP가 적용된다. @Transactional 어노테이션이 특정 클래스나 메소드에 하나라도 있으면 트랜잭션 AOP는 프록시를 만들어서 스프링 컨테이너에 등록한다. 즉 실제 객체(BasicService)가 아닌 프록시 객체(BasicService$$CGLIB)가 스프링 빈에 등록된다.이때 프록시 객체는 원본 객체를 상속받고, 내부에 실제 객체(BasicService)를 참조한다. 애플리케이션..

Backend/Spring 2024.01.16

스프링의 트랜잭션

스프링 없이 트랜잭션을 적용한 예제 우선 스프링 없이 트랜잭션을 적용한 예제를 살펴보자. 애플리케이션에서 트랜잭션을 적용할 때 주의할 점은 다음과 같다. 트랜잭션은 비즈니스 로직이 있는 서비스 계층에서 시작해야 한다. 비즈니스 로직에서 예외가 발생하면 비즈니스 로직에서 실행된 모든 부분이 함께 롤백되어야 하기 때문이다. 그런데 트랜잭션을 시작하려면, 우선 커넥션이 있어야 한다. 따라서 서비스 계층에서 커넥션을 획득하고, 트랜잭션 종료(커밋/롤백) 후에 커넥션을 종료해야 한다. 트랜잭션을 사용하는 동안 실행되는 로직들은 모두 같은 커넥션을 사용해야 한다. 그래야 DB의 같은 세션을 사용하여 정상적으로 트랜잭션이 동작할 수 있다. 트랜잭션을 적용한 예제는 다음과 같다. @Slf4j @RequiredArgsC..

Backend/Spring 2024.01.16

값 타입 컬렉션

JPA의 데이터 타입 JPA의 데이터 타입을 크게 분류하면 엔티티 타입과 값 타입으로 나눌 수 있다. 엔티티 타입 @Entity로 정의하는 객체 데이터가 변해도 식별자를 통해 지속적으로 추적이 가능하다. 값 타입 종류 기본 값 타입: 기본 타입, 래퍼 클래스 , String처럼 자바가 제공하는 기본 데이터 타입 임베디드 타입: JPA에서 사용자가 정의한 값 타입 컬렉션 값 타입: 두개 이상의 값 타입을 저장할 때 사용 식별자가 없으므로 변경시 추적이 불가능하며 생명주기를 엔티티에 의존한다. 값 타입 컬렉션(컬렉션 값 타입) 값 타입을 두개 이상 저장하려면 컬렉션에 보관하고, @ElementCollection과 @CollectionTable을 사용하면 된다. @Entity public class Membe..

Backend/JPA 2024.01.13

스프링의 메시지 기능(MessageSource)

MessageSource 메시지 관리 기능을 사용하려면 스프링이 제공하는 MessageSource를 사용하면 된다. MessageSource는 다음과 같이 인터페이스 형태이다. public interface MessageSource { @Nullable String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale); String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException; String getMessage(MessageSourceResolvable resolva..

Backend/Spring 2024.01.11

BindingResult(FieldError, ObjectError), MessageCodesResolver를 통한 오류 코드 생성, Bean Validation

BindingResult BindingResult는 스프링이 제공하는 검증 오류를 보관하는 객체이다. 검증 오류가 발생하면 BindingResult 객체에 담아두면 된다. @PostMapping("/add") public String addItem(@ModelAttribute Item item, BindingResult bindingResult, RedirectAttributes redirectAttributes) { // 필드 예외 if (!StringUtils.hasText(item.getItemName())) { bindingResult.addError(new FieldError("item", "itemName", "상품 이름은 필수입니다.")); } if (item.getPrice() == nul..

Backend/Spring 2024.01.11

JPQL의 소개와 기본 문법

JPQL JPQL은 Java Persistence Query Language의 약자로, JPA가 지원하는 객체지향 쿼리 언어이다. ORM을 사용하면 데이터베이스 테이블이 아닌 엔티티 객체를 대상으로 개발하므로 검색도 테이블이 아닌 엔티티 객체를 대상으로 하는 방법이 필요하다. JPQL은 이런 문제를 해결하기 위해 만들어졌다. JPQL의 특징은 다음과 같다. SQL이 데이터베이스 테이블을 대상으로 하는 데이터 중심의 쿼리라면, JPQL은 객체를 대상으로 하는 객체지향 쿼리이다. SQL을 추상화해서 특정 데이터베이스 SQL에 의존하지 않는다. JPQL은 결국 SQL로 변환된다. JPQL을 사용하면 JPA는 이 JPQL을 분석한 다음 적절한 SQL을 만들어 데이터베이스를 조회한다. 그리고 조회한 결과로 엔티티..

Backend/JPA 2024.01.10

HttpMessageConverter, ArgumentResolver, MappingJackson2HttpMessageConverter(JSON을 이용한 @RequestBody/@ResponseBody의 동작 원리)

@RequestBody는 클라이언트 측에서 보낸 HTTP 요청 메시지 바디의 데이터를 자바 객체로 변환해준다. 그리고 @ResponseBody는 객체 반환시 객체가 JSON 형태로 변환되어 응답이 나가도록 해준다. 이들의 동작 원리를 이해하기 위해서는 직렬화/역직렬화의 개념과 스프링 MVC에서 제공하는 HttpMessageConverter에 대해 알아야 한다. 직렬화/역직렬화 직렬화(Serialization)는 객체를 문자열 또는 바이트 스트림으로 변환하는 것을 의미한다. 반대로 역직렬화(Deserialization)는 문자열 또는 바이트 스트림을 다시 객체로 변환하는 것을 의미한다. 즉 @RequestBody는 클라이언트 측에서 보낸 HTTP 요청 메시지 바디의 데이터를 자바 객체로 변환하는 역직렬화..

Backend/Spring 2024.01.10

영속성 전이(cascade)와 고아 객체

영속성 전이(cascade) 특정 엔티티를 영속 상태로 만들 때 연관된 엔티티도 함께 영속 상태로 만들고 싶으면 영속성 전이 기능을 사용하면 된다. 예를 들어 엔티티를 저장하거나 삭제할 때 연관된 엔티티도 함께 저장하거나 삭제하는 경우이다. JPA는 cascade 옵션으로 영속성 전이를 제공한다. public enum CascadeType { ALL, // 모두 적용 PERSIST, // 양속 MERGE, // 병힙 REMOVE, // 삭제 REFRESH, // REFRESF DETACH // DETACH } cascade 옵션 적용 전 예를 들어 다음과 같이 부모와 자식이 일대다 관계로 정의되어 있다고 하자. @Entity public class Parent { @Id @GeneratedValue pr..

Backend/JPA 2024.01.09