본문 바로가기

📕 Spring Framework/Spring 개념 정리11

Bean 등록에 대한 재고 SpringBoot에서 Bean을 등록하는 방법은 무엇이 있을까. 1. 클래스에 직접 @Component 애노테이션을 사용하는 방식 2. @Configuration 애노테이션을 활용해 @Bean 등록하는 방식 위 2가지 방식이 보편적이다. 내가 지금까지 진행했던 보통의 애플리케이션 개발 과정에서는 1번을 압도적으로 많이 사용했던 것 같다. @Configuration 방식의 경우, 통상 외부 라이브러리를 Bean으로 등록하기 위함이라며 면접 질문에서 정석적으로 회자된다. 그 고정 관념 탓에, 나의 경우도 2번 방식은 외부 설정 이외에 사용하지 않았었다. Java9에서 나온, 새로운 추상화 개념인 모듈이라는 개념이 있다. 모듈에는 종속성(dependency)의 개념이 있으며, Public API를 내보내고 .. 2024. 10. 12.
Spring boot multi datasource 등록 시 주의 사항 Spring Boot Multi datasource 등록 시 주의 사항최근 진행했던 프로젝트는 외부 휴무일 정보 API를 호출하여 DB에 적재하는 월배치용 Spring Batch 애플리케이션을 개발하는 것이었다.회사에는 여러가지 DataBase가 있는데, 그 중 메인 DB를 사용하기로 했고, spring batch 용 DB는 따로 사용하게 되었다.그래서 멀티 datasource bean 을 등록해줘야 했다.그 과정에서 정말 기초적이지만 실수했던 부분을 설명해보겠다.Multi Datasource하나의 프로젝트에서 여러 개의 데이터베이스를 연결하는 것.spring 에서는 기본적으로 yaml 파일을 통해 쉽게 datasource 구성이 가능하다.따로 java 코드로 bean 을 등록할 필요가 없을 것이다.하지.. 2024. 9. 18.
[Spring data JPA] N+1 문제 해결 이렇게 이루어진 ERD 모델이 있다. (예시) 조건에 맞춰 불러오고자 하는 Data는 세 테이블의 정보를 모두 필요로 한다. 이때 Fetch join을 고려해볼 수 있다. Permission 입장에서 user와 document를 두번 다 fetch join 할 수 있지만, 이능 데이터 베이스 성능 상 엄청난 문제가 있다. 데이터가 많을 경우, 연관된 엔티티의 수를 제한하는 방법으로 쿼리를 나눠서 발생시키는 것도 좋은 방법일 것이다. 해당 엔티티들은 모두 FetchType.LAZY 로 설정되어 있다. 기존 쿼리 : val documents = documentQueryService.findDocumentsByIdFetchJoinPermissions(projectId) return Response.UserPe.. 2023. 2. 28.
[Reactive Programming] 비동기-논블로킹 프로그래밍 동기 프로그래밍 (Synchronous) 작업의 실행 흐름은 순차적으로 동작 코드를 파악하기 쉽고 결과를 쉽게 예측 가능하므로 디버깅이 쉬움 특정 작업 중 다른 작업을 할 수 없다는 단점 비동기 프로그래밍 (Asynchronous) 작업의 실행 흐름은 기본적으로 순차적이지 않음 현재 실행 중인 작업 이외에 다른 작업 가능. 클라이언트, 서버 등 모든 환경에서 유용하게 사용 가능 대표적으로 CallBack, Promise, Future, Coroutine 등이 있다. 비동기 프로그래밍 구현 방식 - Kotlin Thread 가장 기본이 되는 방식 Runnable 인터페이스를 구현하여 구현 하나의 스레드 - 싱글 스레드, 다중 스레드 - 멀티스레드 fun main() { for (i in 0..5) { va.. 2023. 2. 11.
[@DataJpaTest] h2 인메모리 db를 이용한 테스트 설정 방법 서론 테스트 코드를 작성하는 것은 매우 중요하다고 익히 들었고, 필수적인 영역이기 때문에 이에 항상 만전을 기하고 있다. 모든 케이스를 테스트할 이유는 없기 때문에, 크게 경우를 나누어 필요하다고 생각하는 부분만 시나리오, 통합, 단위 테스트를 나누어 진행하는 것이 효율적이라고 들었다. 배포를 계속 해오면서 jar 파일을 빌드하는 도중 테스트를 제외하는 것은 무의미하다고 판단했기 때문에, 모든 테스트를 어떤 환경에서든 돌아 갈 수 있게 고민을 했던 기억이 있다. 이렇게 하나하나 완성도 있게 쌓아나가는 공부를 하는 것이 속도는 느리지만, 유의미한 발전 과정이라 느낀다. 이번에 대규모 리팩토링을 실시하면서 코드 수정 및 구조가 크게 개편되었고, 테스트 코드도 변경 사항이 많이 생겨서 다 수정했다. persi.. 2022. 12. 21.
WebFlux는 무엇이고, 왜 나왔고, 언제 쓰이는가? 어제 Cart API 코드 리팩터링을 마무리하고, 리뷰를 받기 위해 PR을 올렸다. 클린 한 코드로 작성하려고 노력하기 위해 리뷰어님이 주신 의견을 되뇌고, 클린 코드를 작성하기 위한 방법을 구글링을 통해 하루 종일 모니터를 노려보며 클래스 간 책임을 나누어 보았다. 빨리 성장하고 싶다!! 리뷰를 앞두고, 카카오페이를 이용한 도메인 코드들을 리팩터링 하기 앞서, 기존에 외부 API와 통신하기 위해 사용하던 템플릿인 RestTemplate의 대체 여부에 대해 떠올랐다. RestTemplate은 deprecated 되었으므로, WebClient의 사용을 고려해보라는 의견을 받았다. WebClient에 대해 알아보다가 동기/비동기, 블로킹/논블로킹이라는 개념의 정의에 대해 다시 공부하게 되었고, 나아가 Web.. 2022. 8. 31.
Spring Security [2] - 예외 처리 AuthenticationEntryPoint & AccessDeniedHandler 서큐리티를 도입하며 인증, 인가의 과정을 마쳤다. 이제 인증 및 인가 작업에서 발생하는 예외에 대해서 처리를 해주어야 하는데, 한 가지 생각해봐야 하는 문제가 있다. 스프링 서큐리티는 필터에 기반한 체이닝 구조이므로, 스프링 컨테이너까지 요청이 도달하지 않는다. 따라서, @ExceptionHandler를 통한 편한 예외 처리가 불가하다. 직접 Try - catch로 잡아서 응답을 내려주는 방법 밖엔 없다. 하지만, 스프링 서큐리티가 그렇게 허술하진 않다. 서큐리티 필터 체인의 구조를 보면 마지막 즈음에 예외를 처리하는 필터가 있는 것을 확인할 수 있다. 여기서 주로 사용하는 AuthenticationEntryPoint와 AccessDeniedHandler를 구현해 인증 및 인가 과정에서 일어난 예외에 대.. 2022. 8. 21.
Spring Security [1] - JWT를 이용한 REST API 인증과 인가 기존 인증은 JWT를 이용한 필터로, 인가는 인터셉터로 애노테이션을 정의해 손수 구현했었다. 이번에 리팩터링을 하면서, 스프링이 제공하는 보안 관련 프레임워크인 서큐리티를 사용해보자는 결정을 내려 도입하게 되었다. 어렵다고는 얼핏 들었지만, 이렇게 오래 걸릴 줄 몰랐다. 여러 블로그들을 참조하고, 잘 읽히지도 않는 공식문서들을 보아도 도무지 이해가 가지 않았다. 일단 머릿속에 그려져야 감이 잡히는데, 이건 뭐 필터도 여러 개이며 구현체도 왜 이렇게 많은지 그에 맞는 책임과 역할이 도저히 감이 오지 않는다. 전부 추상화 되어 있어 커스텀해서 사용하기는 편하게 되었다는데, 전반적으로 모든 내용을 이해하기엔 쉽지 않기도 하고 따로 공부가 필요한 프레임워크라고 생각한다. 거진 1주 반이 넘어서야 내가 구현하고자.. 2022. 8. 18.
2022.05.17 「@Transactional 옵션 및 성능」 스프링 부트 프로젝트를 하던 도중 Service 클래스에서 @Transactional 사용에 옵션을 설정할 수 있다는 것을 처음 알았다. 옵션을 한번 추가해보라는 피드백을 받고 한번 이 에너테이션에 대해 알아보기로 했다. 프로그램 성능에 직접적인 영향을 끼칠 수도 있는 중요한 옵션이기 때문에 한번 정리를 해보겠다. 트랜잭션(Transaction)의 정의 데이터 베이스의 상태를 변경할 때, 한번에 수행되어야 하는 연산 트랜잭션 ACID 성질 원자성(Atomicity) : 트랜잭션이 DB에 모두 반영되거나, 전혀 반영되지 않거나 해야한다. 일관성(Consistency) : 트랜잭션은 일관성 있는 DB 상태를 유지해야한다. 작업 처리의 결과가 항상 일관되어야 함. 독립성(Isolation) : 동시에 실행되는.. 2022. 5. 17.
2022.05.13 「Session과 Token(Jwt) & 인증과 인가」 현재 진행 중인 프로젝트에서 로그인을 진행 중인데 기존에 로그인은 세션으로만 진행했었다. 로그인을 구현하는 방식은 여러 가지라고 배웠는데 그중 세션만 이용해봤기 때문에 토큰을 이용한 인증 경험도 필요하다고 생각을 했다. 그중 내 서비스에 대해 또 서비스 확장성에 대해 확실히 맞는 인증 방식을 결정해야겠다고 생각을 했고, 세션과 토큰의 사용처와 개념에 대해 정리를 해보려고 한다. 인증과 인가 인증(Authentication) 서비스의 사용자가 맞는지 확인하는 과정 대게 로그인하는 과정 인가(Authorization) 인증이 완료된 사용자에게 리소스 접근 가능하도록 사용 권한을 부여하는 작업 액세스가 허용된 데이터 및 해당 데이터로 할 수 있는 모든 작업을 지정함 HTTP의 특성 http는 stateless.. 2022. 5. 13.
2022.05.08 「RestFul한 api? & ResponseEntity의 사용」 어김 없이 스프링 프로젝트를 진행중이다. 일주일 전 View를 없애고 좀 더 Back에 집중된 api를 설계하는 것으로 초점을 맞췄다. handler 메서드의 반환 값을 단순히 json 형식으로 보여주면 되는 거 아니냐? 라고 생각을 했지만 검색을 여러번 해보니 정말 확실하게 알기 전까지는 함부로 생각하지 말자라는 결론을 내렸다.. 어렴풋이 배웠던 rest api가 떠올랐고 제대로 공부를 하고 이용을 해서 restful한 api를 만들어야겠다는 생각에 개념정리를 결심하게 되었다. 또 반환 타입으로 ResponseEntity의 사용이 많은데 이 타입을 왜 사용하는지도 한번 알아봐야겠다. Rest가 정확히 뭘까?? Representational State Transfer -> 자원을 이름으로 구분하여 해당 .. 2022. 5. 8.
반응형