Spring

토비님의 유튜브 영상을 보던 중 내부 클래스를 스프링 컨테이너에 등록 가능한지 확인해보는 컨텐츠가 있었다. 제목을 읽고 확실히 답을 해볼 수 없었기에 영상을 기반으로 정리를 해보고자 한다. 내부 클래스 vs 정적 중첩 클래스 분석에 앞서, 기존에 헷갈렸던 개념에 대해 한번 정리를 하고자 한다. @Configuration public class NestedClass { @Component public static class StaticNestedClass{ } public static void main(String[] args) { // 외부 클래스와 상관 없이 생성 가능! StaticNestedClass staticNestedClass = new StaticNestedClass(); } } 위의 코드에서..
공유 자원에 대한 동시 접근을 제어하기 위해 우리는 락 메커니즘을 사용할 수 있고, 그중에서도 분산 서버 환경에서 동시성을 제어하기 위해 분산락을 사용할 수 있다. 분산락을 적용하는 것만으로도 대부분의 동시성 문제를 해결할 수 있다. 하지만 대규모 분산 환경에서는 외부 시스템과의 연결 문제, 네트워크 지연 문제 등 우리가 예측할 수 없는 예외 상황이 얼마든지 발생할 수 있다. 지금부터 예외가 발생할 수 있는 시나리오를 재현해보고, Redis 기반의 분산락과 JPA의 낙관적 락을 함께 적용해서 문제를 해결하는 과정을 알아보자. 또한 락을 사용하게 되면 비즈니스 로직에 락을 획득하고 해제하기 위한 코드가 침범하게 된다. 이를 방지하기 위해 락 관련 코드를 AOP로 추출하는 과정까지 진행해보도록 하자. 발생 ..
인턴을 진행하면서 실제 실무에서 사용하는 코드를 접할 수 있는 기회를 가지게 됐다. 객체 지향의 장점을 살리기 위한 다양한 디자인 패턴들이 코드에 자연스럽게 녹아있는걸 알 수 있었다. 최근 클린 아키텍처에 대한 관심이 커져서 패키지 구조나 계층 간 매핑 전략 등에 신경을 많이 쓰고 있었지만, 이번을 계기로 객체 지향의 특징을 잘 지키는 코드를 작성하는 방법에 대한 고민을 많이 하게 되었다. 그러던 중, 망나니 개발자님의 블로그 글 중에 팩토리 패턴에 대한 글을 발견했고, 앞으로 팀 프로젝트나 실무에서 많이 사용할만한 패턴인 것 같아서 블로그에 정리를 하려고 한다. // 구체 클래스들이 구현하게 될 LoginService 인터페이스이다. public interface LoginService { // if-..
· Spring/JPA
현재 진행하고 있는 프로젝트의 메인 페이지를 페이징 기능을 사용해서 구현했다. 모바일 환경에 최적화해서 개발했기 때문에 Offset과 Limit을 사용한 게시판 형식의 기본 페이징이 아닌, 무한 스크롤 방식을 사용하기로 결정 했다. 아래에 보이는 망고플레이트의 페이징 기능을 구현했다고 보면 된다. 제목에서 설명한대로 무한 스크롤을 구현하기 위해서 No Offset 방식과 Slice를 사용했는데, 두 가지 방식이 무엇이고, 왜 사용해야 하는지 알아보자. No Offset 방식은 무엇이고 왜 사용하는가 기존의 페이징은 offset과 limit을 사용해서 페이징할 범위를 정한다. 이 방식은 초반에는 효율이 나쁘지 않지만 뒤로 갈수록 효율이 급격히 떨어진다는 단점이 있다. 왜 이런 현상이 발생하는지 알아보자. ..
현재 진행하고 있는 프로젝트에서 로그인 로직을 Spring security와 JWT로 구현했다. 구현 중에 인증 예외와 JWT 관련 예외 처리를 분리하기 위해 많은 노력을 했는데 이 과정을 공유하고자 한다. 우선 로그인하지 않은 사용자가 허용되지 않은 API에 접근할때 발생하는 인증 예외의 메커니즘에 대해 살펴보자. 기본 인증 예외 처리 방법 SpringConfig 클래스에는 위의 사진과 같이 권한 설정이 되어있다. /api 로 시작하는 API로는 비 로그인 사용자가 접근할 수 없다. API를 호출하면 위와 같은 응답이 반환되도록 설정했다. 응답은 AuthenticationEntryPoint에서 커스터마이징했다. AuthenticationEntryPoint의 코드를 살펴보자. public class Re..
@Authentication을 통한 인증 유저를 가져오는 과정에서 겪은 문제와 제가 해결한 방법에 대해 공유하고자 합니다. @AuthenticationPrincipal 어노테이션의 사용법을 구글에 검색했을때, 많은 블로그에서 UserDetailsService를 구현한 CustomUserDetailsService의 loadUserByUsername 메서드에서 반환해준 값을 파라미터로 직접 받아 사용할 수 있다고 알려줬습니다. loadUserByUsername 메서드에서 반환하는 UserPrincipal 객체입니다. UserDetails를 구현하는 방식으로 만들었습니다. 전체 코드 중 일부를 가져온 것이기 때문에 '이런 객체를 반환하도록 만들었구나' 정도만 생각해주면 감사하겠습니다. 이제 Controller..
📌 김영한님의 강의를 바탕으로 정리한 글입니다. [ @Aspect란? ] 스프링 어플리케이션에 프록시를 적용하려면 포인트컷과 어드바이스로 구성된 어드바이저를 스프링 빈으로 등록해야 한다. 자동 프록시 생성기는 스프링 컨테이너에서 어드바이저를 찾아서 나머지 스프링 빈들에 프록시를 자동으로 적용해준다. 스프링은 @Aspect 라는 어노테이션을 사용해서 어드바이져를 쉽게 만들수 있게 해준다. @Aspect는 AspectJ 프로젝트에서 제공해주는 어노테이션이다. 하지만 AspectJ 프로젝트 자체를 사용하는것은 아니다. 스프링은 AspectJ의 기능을 차용해서 사용하는 것이다. @Aspect를 사용하는 방법을 살펴보자 @Component @Aspect // 해당 클래스를 어드바이져로 만들 수 있게 해준다. @S..
스프링 타입 컨버터란? HTTP 쿼리스트링을 통해 전해지는 모든것은 문자로 인식된다. 하지만 localhost:8080/test?itemId=10 처럼 쿼리스트링을 보냈을때, 컨트롤러에서는 Long itemId의 숫자 타입으로 입력받을 수 있다. 이처럼 형변환이 되려면 매개변수를 처리하는 과정에서 자동으로 호출되는 변환 기능이 있어야 한다. 이것이 스프링 타입 컨버터이다. 스프링 타입 컨버터의 아래의 어노테이션을 대상으로 사용 가능하다. - @RequestParam - @ModelAttribute - @PathVariable 스프링 타입 컨버터 사용 스프링 타입 컨버터는 Converter라는 인터페이스를 구현해서 사용할 수 있다. Converter 형태에서 S는 입력값의 형태를, T에는 변환하길 원하는 ..
Jemlog
'Spring' 카테고리의 글 목록