spring/core
-
Spring @RequestScope 빈 스코프spring/core 2022. 8. 7. 16:48
스프링에서 관리하는 빈의 스코프는 기본값이 싱글톤이다. 웹애플리케이션을 운영하는 경우 사용자마다 다른 데이터를 갖고 서버에 진입할 수 있고 다른 데이터를 갖는다면 싱글턴빈으로는 그 값을 표현할 수 없다. 사용자마다 다른 데이터를 갖는 빈을 마치 스프링이 관리하는 싱글턴 빈처럼 사용할 수는 없을까? @RequestScope 사용 @Component @RequestScope @Setter @Getter public class HttpRequest{ private String headerMessage; private int count; } @Slf4j @RequiredArgsConstructor @RequestMapping @RestController public class TestController { pr..
-
Spring 에러 핸들링spring/core 2021. 10. 2. 18:05
들어가며 웹애플리케이션 API서버를 만들 때 서버 퀄리티를 결정하는 건 인증과 에러처리라고 생각한다. 인증은 그 방식이 무수히 많고 깊이도 어마어마하지만 인증은(스프링 한정) 어느정도 정형화된 패턴이 있다. 스프링이 어떤 방식으로 에러를 핸들링하는지 그 방식을 커스텀하는 방법은 무엇인지 알아보자^^ @ExceptionHandler 이런식으로 컨트롤러에서 에러를 핸들링하는 메서드 위에 @ExceptionHandler 에노테이션을 붙여주면 잘 동작한다. 다만, 핸들링을 추가하려면 반드시 컨트롤러 수정이 필요하고 핸들링 범위가 딱 해당 컨트롤러만 적용된다는 점이 단점이다. HandlerExceptionResolver spring에서 기본적으로 제공하는 에러핸들러이고 커스텀해서 이용하는 방법도 있다. Handl..
-
Spring @Scheduled 사용 및 동작원리spring/core 2021. 5. 19. 16:20
배경 프로젝트에서 멤버가 회원가입하고 로그인하는 과정을 살펴보자. 양식을 입력한 유저는 회원가입 요청을 서버에 하게 된다. 서버는 DB에 회원정보를 저장하는데 그 권한을 PRE로 설정하고 회원 이메일로 인증코드가 포함된 URL을 보낸다. 회원가입한 유저는 본인 이메일로 접속해 이 메일의 URL을 클릭하면 서버가 회원의 권한을 PRE에서 USER로 바꾸고 정상적으로 로그인을 처리할 수 있도록 하게 된다. 서버 내부적으로 유저이메일을 key값으로, 인증코드를 value로 외부 데이터베이스인 redis에 저장하게 된다. 만약 회원가입한 유저가 회원가입만 진행한 후 인증을 제때 처리하지 않으면 어떻게 될까? 레디스에 저장하는 인증코드는 적절한 expire를 갖는 게 맞다. 레디스 저장소가 expire된다면 유저..
-
Spring Interceptor 사용 및 동작 정리spring/core 2021. 5. 14. 10:59
배경 인터셉터가 서블릿에서 어떻게 동작하는지 실습해보자 인터셉터란? 필터, 인터셉터, AOP 모두 어떤 작업을 기준으로 전과 후에 부가기능을 추가해주는 작업을 한다. 필터는 서블릿 작업 전과후, 인터셉터는 핸들러매핑 작업 전과후, AOP는 메서드 처리 전과후에 부가기능을 추가한다. 핸들러매핑은 요청의 URL과 메서드로 구분되니 인터셉터도 비슷한 메카니즘으로 적용할 핸들러매핑을 정할 수 있다는 걸 알 수 있다. 실습 일단 /hello라는 GET 요청에 대해 "middle print!"를 출력해주는 핸들러매핑을 만들었다. 다음으로 HandlerInterceptor를 구현한 HelloInterceptor클래스를 만들고 preHandle()과 postHandle()를 오버라이딩했다. 한가지 특이한 점은 Hell..
-
스프링 DI 방법spring/core 2021. 5. 6. 17:00
배경 처음에 잘 배워서 그런지 스프링의 빈을 생성할 때 사용하는 DI방법에 대해 큰 고민을 하지 않았다. 당연히 롬복 + final + 생성자를 조합한 DI를 활용했다. 당연한 건 없다. 스프링이 제시하는 DI에는 어떤 게 있는지 그리고 왜 당연한 조합을 당연히 썼는지 생각하자. 필드 DI 공식문서에는 아예 소개된 방법도 아니고 인텔리제이는 필드 DI를 쓰지말라고 경고까지 한다. 그래도 필드 DI를 이용해 애플리케이션을 구동해보면 잘된다. 왜 스프링은 필드 DI를 DI방식에서 배제했을까? 장점 코드가 간결하고 의존성을 추가 또는 삭제해도 영향 받는 코드의 양이 적다. (관점에 따라 이건 단점이다-> 단일책임원칙 위배 가능성 up) 단점 우선 가장 큰 단점으로 필드 DI를 이용하면 반드시 스프링 컨테이너를..
-
스프링 부트 자동설정 과정spring/core 2021. 4. 6. 14:54
배경 스프링을 알기 이전에 스프링부트를 접했고, 대략 5개월 정도 스프링 부트를 공부하고 있다. IDE 또는 커맨드라인에서 java -jar ...jar를 이용해 수도 없이 애플리케이션을 실행했고 그런가보다하고 그냥 사용해 왔다. 최근에 토비의 스프링으로 스프링에 대해 공부하고 있는데, 스프링을 이용해서 WAS 하나를 띄우기 위해 굉장히 복잡한설정과 많은 작업이 이루어진다는 걸 알아가고 있다. 그러한 굉장히 복잡한 작업을 나는dependency추가와 실행버튼 클릭만으로 자동으로 수행하고 있었다. 늘 그렇듯 추상화된 Layer를 알고 경험해봤다면 그 경험과 지식을 구체화시켜야 한다. 딥하게는 아니더라도 디버거를 따라가 보며 자동화된 설정을 경험해보자^^ www.youtube.com/watch?v=ssT24..
-
DispatcherServlet에서 요청을 처리하는 과정spring/core 2021. 4. 5. 12:48
배경 추상적으로 이건 이렇게 되고 그 다음 이렇게 돼를 아는 건 중요하지만, 좀 더 시간이 지나면 이 과정을 코드로 이해해볼 필요가 있다. 아키텍처를 코드레벨로 이해하는 건 굉장한 기반 지식이 되기 때문이다^^. 추상적인 DispatcherServlet의 요청 처리 과정 Filter를 거친 요청은 최종적으로 DispatcherServlet에서 처리한다. 이때부터 과정을 쭉 스캔해보자. 1) 서블릿에 등록한 핸들러매핑을 순회하며 요청에 맞는 핸들러매핑을 찾아낸다.(요청을 수행할 클래스) 2) 핸들러매핑을 찾는 똑같은 프로세스로 핸들러어댑터를 찾는다(어댑터 패턴을 위해) 3) 어댑터를 이용해 핸들러매핑(클래스의 메서드)를 수행한다 코드를 통해 눈으로 살펴보자 일단 그 이전 처리를 아주 간단하게 정리하면 Di..
-
HandlerMethodArgumentResolver 동작 원리spring/core 2021. 3. 8. 23:06
배경 프로젝트에서 가장 기본 도메인인 회원의 CRUD를 구현하고 있었다. JPA를 이용해 큰 어려움 없이 CR기능은 구현했고 스무스하게 UD관련 기능을 구현했다. 별 고민없이 클라이언트에서 회원id와 함께 변경에 필요한 데이터를 api서버로 전달했다. api서버에서는 회원id와 나머지 변경을 원하는 데이터를 DTO로 받아 작업을 처리했다. 포스트맨을 이용해 간단히 테스트를 진행했는데 내 로직에 큰 결함이 있는 걸 알았다. id를 클라이언트에서 넘긴 후 그 id로 조회한 회원의 데이터를 수정할 수 있다면 어떤 회원이 악의적으로 다른 회원의 데이터를 수정할 수 있었다. 즉, 서버에서 인증한 회원이라면 다른 회원의 정보를 임의의 id를 통해 접근할 수 있는 것이었다. 이 문제를 해결하기 위해 id에 의존한 회..