Server

    Custom Advisor 에 @Transactional 설정시 미적용 문제

    Custom Advisor 에 @Transactional 설정시 미적용 문제

    @Transactional은 Spring AOP 를 사용하여 동작한다. 그럼 만약 아래와 같은 상황처럼 Custom Advisor[customAdvisor] 와 해당 Adivsor를 적용하려는 메서드[test] 에 @Transactional 설정을 아래와 같이 했을 경우 어떤 구조로 동작할까? @Service public class TestService { @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true) public void test() { log.info("Test"); } } @Aspect @Component public class AspectConfig { private final TestJpaRepository tes..

    [Lombok] @Builder 로 객체 생성시, 초기화 안해준 필드 null 값으로 세팅

    Lombok의 @Builder 로 객체를 생성하는 경우가 종종 있을 것이다. 원하는 필드에만 값을 세팅할 수 있고, 파라미터의 순서를 고려하지 않아도 되기 때문에 상당히 편하다. 하지만 원하는 필드에만 값을 세팅할 시에, 값을 세팅하지 않은 필드에는 null 값이 들어가는 문제가 생긴다. default로 별다른 값을 설정을 하지 않았을 때는 문제가 되지 않지만, 기본 값 설정을 한 경우에는 default 값에 null 값이 덮어씌어지게 된다. 만약 이후에 해당 필드의 메서드를 호출하는 경우가 있다면 NullPointerException 이 발생할 것이다. 이를 방지하기 위한 방법으로 필드에 'final' 을 설정하면 된다. 이에 따라 초기 설정값을 보존할 수 있다. 참조 - https://velog.io..

    [JPA] Cascade.REMOVE 를 이용하여 연관 관계 삭제 시도 시 발생하는 [Cannot delete or update a parent row: a foreign key constraint fails]

    문제 일대다 관계가 연쇄적으로 연결된 테이블 구조에서, 부모 Entity 를 Cascade.REMOVE 를 이용하여 삭제함으로써 그 아래 연결된 자식들을 한 번에 삭제하려고 하였다. Spring Data JPA 를 사용하고 있는 상황에서, 한 번의 sql 문으로 삭제하도록 아래와 같이 네이티브 쿼리을 작성하여 호출하였다. public interface DiaryRepository extends JpaRepository { @Modifying @Query(value = "DELETE FROM diary WHERE member_id = :memberId AND write_date LIKE :likeFormat" , nativeQuery = true) void deleteByMemberAndWriteDate(..

    [Spring] JWT 사용 시, Controller 에서의 Entity 접근.

    JWT를 사용하여 인증/인가 처리를 할 경우, 토큰에서 사용자 정보를 빼내어서 요청 처리를 하는 경우가 있다. 그럴 경우 Controller 에서 Authentication 인자 설정을 통해 인증 정보를 받아오고, 해당 정보로 사용자 정보를 추출해야 하는데, 이 사용자 정보 추출을 Controller 에서 하게 된다면 Web 계층에 Entity 가 들어가게 된다. 그렇다면 이를 방지하기 위해 Service 메서드 호출과 동시에 사용자 인증 정보를 넘겨주어 Service 단에서 getPrincipal 메서드를 통해 사용자 정보를 가져오는 것이 맞는 것일까?

    [Spring] 서블릿 HTTP 세션

    서블릿에서 HTTP 세션을 어떠한 방식으로 만들어줄까? 하나의 HTTP 요청이 들어왔을 오고 이후 로직에서 세션 생성 요청이 있다면, 서블릿 컨테이너에서 세션을 만들고JSessionId를 부여해준다. 이렇게 만들어진 JSessionId 만 알고 있다면 만들어진 세션에 접근하여 원하는 정보들을 저장하거나 삭제할 수 있다. 그리고 요청이 끝난 뒤에도 해당 세션을 서블릿 컨테이너에서 관리하고 있다가 JSessionId를 쿠키로 가진 HTTP 요청이 들어올 경우, 서블릿 컨테이너에서 JSessionId 로 가지고 있는 세션들 중 일치하는 세션ID가 있는지 확인한다. 만약 일치하는 세션이 있다면 해당 요청에서 접근할 수 있도록 설정해준다. 위와 같은 방식으로 서블릿은 세션을 편하게 생성하고 사용할 수 있게끔 만들..

    [Spring] 구글 OAuth 2.0 과정

    해당 글은 Spring 작동원리에 대한 개인적인 예상을 작성 해놓은 글 입니다. 구글 Oauth2.0의 과정의 위의 이미지와 같이 일어난다. 여기서 access_token 으로 유저정보를 받아온 뒤의 과정을 설명하겠다. @Slf4j @Service public class CustomOAuth2UserService implements OAuth2UserService { @Override public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { OAuth2UserService oAuth2UserService = new DefaultOAuth2UserService(); OAuth2User oAu..

    [Spring] Spring Security 동작 과정.

    해당 글은 Spring 작동원리에 대한 개인적인 예상을 작성 해놓은 글 입니다. Security 설정 클래스에서 permit 된 경로로 요청이 들어올 때. 허용된 주소로 요청이 들어왔을 때, security filter 에서 setAuthentication 을 통해 security context 에 인증 정보를 넣어주지 않는다. 하지만 이후에 허용된 주소일 경우에는 인증 정보 체크를 하지 않기에 정상적으로 다음 단계로 넘어간다. Security 설정 클래스에서 permit 되지 않은 경로로 요청이 들어올 때. 1. 권한이 있을 때. 허영되지 않은 주소로 요청이 들어왔을 때, security filter 에서 요청 헤더에 존재하는 정보(토큰 등)를 바탕으로 security context 에 인증 정보를 넣..

    Spring에서 요청이 들어왔을 때 동작 과정

    해당 글은 Spring 작동원리에 대한 개인적인 예상을 작성 해놓은 글 입니다. 설정 서버를 실행하면 Component Scan 이 이루어져 스캔 범위내에 있는 class들을 스프링 컨테이너에 Bean으로 등록한다. 그리고 Controller Method들 위에 명시된 @RequestMapping value를 reflection method로 분석해서 DispatcherServlet에 생성한 저장소(ex.Map)에 URI 와 해당 Controller 레퍼런스 값을 key, value로 저장 해 놓는다. 이후 클라이언트가 /user/login 을 요청했다고 하자. 동작 과정 요청은 DispatcherServlet 에 도달하고, 저장소에서 요청된 URI를 key 값으로 하여 Controller를 찾는다. C..

    [Spring] Session 이용한 로그인 후 인가 과정

    해당 글은 Spring 작동원리에 대한 개인적인 예상을 작성 해놓은 글 입니다. 먼저 Filter 또는 Interceptor 설정에서 허가한 URL이 아닌 경로가 클라이언트로부터 요청된다면, 로그인 화면을 요청하게 끔 Redirect 설정을 한다. 그 다음 로그인 요청이 들어오면, 등록된 회원 정보와 비교한다. 만약 정보 비교에 실패한다면 다시 로그인 화면을 띄워주고, 정보 비교에 성공했다면 getSession() 을 호출하여 Session 값을 생성하거나 가져오고, Session 에 setAttribute() 로 유저 정보를 저장한다. Session 값이 생성되면 그에 따른 Session ID 도 할당되는데, 이 Session ID 를 쿠키 값으로 하여 클라 이언트에 보내준다. 이후 클라이언트는 서버에..

    [Spring] Component Scan 범위

    스프링의 Component Scan 범위는 @ComponentScan이 명시된 클래스가 위치한 디렉토리를 포함해서 그 하위 디렉토리들이다. 스프링 생성 시에 @SpringBootApplication 이 main 메서드를 가진 클래스에 명시되어 있고, 이 어노테이션은 내부적으로 @ComponentScan을 포함하고 있다. 따라서 스프링의 기본적인 Component Scan 범위는 해당 클래스가 위치한 디렉토리를 포함한 하위 디렉토리들이 된다. [Spring] @Component와 컴포넌트 스캔 [Spring] @Component와 컴포넌트 스캔 이번 글에서는 @Component와 이 어노테이션이 어떻게 인식이 되며, 어떻게 사용되는지 알아보도록하자. 1. @ComponentScan의 범위 @Componen..