분류 전체보기 68

스프링을 이용한 aws 파일 업로드

요새 토이 프로젝트 하나씩 올리는게 나름 재밌어져 간다. 내가 만들고 싶었던걸 만드는 기쁨이란 이런것일까..? 이게 바로 개발자의 삶인가..? 나름 잘 맞는 것 같다. 아무쪼록 이번엔 파일 업로드에 대해 다루어 보겠다. 기본적인 요구사항은 다음과 같다. 0. multipart/form-data 또는 multipart 헤더를 이용하여 파일 송수신을 한다. 1. 이미지 자체는 aws의 S3에 저장한다. 2. file 이름이 중복되면 안되므로 file 마다 고유의 무작위 이름이 정해진다. 3. aws에는 S3 bucket의 /test2 디렉터리 밑에 저장하고 데이터 베이스에는 파일 고유의 무작위 이름을 저장한다. 4. 이미지 조회를 요청하면 file 위치로 redirect 한다. 먼저 aws에 이미지를 업로드..

제너릭과 DTO, connection pool을 활용하여 Spring RestTemplate 이용하기

백엔드 특성상 사실 요청을 받아서 응답을 해주는 서버이지 요청을 만드는 역할은 잘 하지 않는다. 뿐만 아니라 서버가 요청을 만들어서 하는 것 보다는 클라이언트 단에서 하는 게 더 맞다고 생각한다. 서버 부하가 심해질 수 밖에 없으니깐. 하지만, 서버에서도 할 경우가 있다. 대표적인 예로 디비 통신. 다른 서버 통신도 있을 수 있고 그럴 경우는 대게 RestTemplate을 사용한다. 이번 글은 최종 프로젝트에서 외부 서버와 통신할 일이 많았었다. 근데 RestTemplate을 사용하다가 불편한 점이 많았어서 라고 호기롭게 도전했다가 생각보다 RestTemplate이 정말 편리한 거구나 ㅋㅋㅋ 그러면 어떻게 하면 효과적으로 중복 코드를 많이 제거하는 방식으로 활용할 수 있을까? 싶어 만들어본 하나의 클래스..

스프링 포인트 거래 시스템

사실상 막학기가 지나면서 여러 회사에 도전하느라 바쁘기도 하고 와중에 방황의 시기를 좀 겪은 것 같아 글을 많이 못썼다. JPA 쪽도 이러쿵 저러쿵 많이 보았는데 쓸 시간이 없기도 했다. 뭐 이런 느낀점은 다른 글에서 생각이 정리되면 적어 보기로 하고, 포인트 거래 시스템에 대해 적어 보기로 하자. 이게 무엇이냐면, 동시성이 최대 이슈인 시스템이다. 동시성에 대한 다양하 예시는 아래와 같을 것이다. 1. 두 개의 트랜잭션이 열리고 5000원을 가지고 있는 사용자에게 3000원과 4000원을 빼갈 수 없도록 해야 한다. 두 트랜 잭션 중 하나의 트랜잭션만 가능해야 한다. 2. 뿐만 아니라 5000원인 사용자에게 두 트랜잭션이 동시에 3000원과 2000원을 전송했을 때, 7000원 8000원도 아닌 100..

스프링(TDD) 테스트 코드 작성

TDD를 만족하기 위해서 단위 테스트 코드 작성하는 법을 공부했었다. 이 글에서 잘 정리하고자 한당. 기본적인 방식은 given-when-then을 따르고자 한다. 이러한 패턴의 장단점도 있다고 하지만, 아직 그러한 깊이는 부족한 것 같다. 나중에 많이 하다 보면 보이겠지? 0. Mock 객체 작성 @MockBean private RecordService recordService; 단위 테스트를 만들기 위해 의존관계 주입 받는 외부 객체는 Mock객체로 만들어 낸다. @Mock과 @MockBean 어노테이션으로 Mock객체를 생성할 수 있다. Spring Boot Container가 테스트 시에 필요하고, Bean이 Container에 존재한다면 @MockBean을 사용하고 아닌 경우에는 @Mock을 사..

AOP 2편[내부 호출과 프록시 기술의 한계, 마무리]

AOP 마지막 글이다! 진짜 이것까지 정리하면 완전정복!! AOP를 알기 전과 지금 알게 되면서 정말 많은 구현을 해보고 싶다. 너무 재미있게 배웠고 이것저것 떠오르는 아이디어가 많다. 기존에 적용했던 프로젝트에도 AOP를 이용하여 좀 더 깔끔하게 정리하고 싶은 욕구도 샘솟는다. 마지막 정리 하기 이전에 영한님께 정말 감사인사 드리고 싶다.. 꼭 영한님 같은 개발자가 될거다. 1. 프록시와 내부 호출 문제 @Transactional 어노테이션을 공부하면서 얼핏 들었던 문제였다. @Slf4j @Component public class CallServiceV0 { public void external(){ log.info("call external"); internal();//내부 메서드 호출(this.in..

AOP 2편 [포인트 컷 분리, 어드바이스 활용, 포인트컷 지시자]

AOP 1편을 잘 마치고 이제 실전에서 적용할 방법들, 주의사항들에 대해 다루어 보자. 1. 포인트컷 아래 사진이 바로 예시 상황이다. Service는 Repository를 의존하고 있고, orderItem()메서드를 호출하면 Repository에서 save메서드를 호출한다. 만약 save의 인자인 itemId가 "ex"이면 예외를 발생시킨다. 지금까지 배운 내용으로는 아래와 같은 코드로 @Aspect를 구현한다. @Slf4j @Aspect public class AspectV1 { @Around("execution(* hello.aop.order..*(..))") public Object doLog(ProceedingJoinPoint joinPoint) throws Throwable{ log.info(..

AOP 1편 [@Aspect, AOP 1편 정리]

이젠 Advisor의 구현체를 만들고 빈으로 등록하면 스프링 자동 프록시 생성기가 어드바이저를 찾아 포인트 컷이 맞으면 프록시를 만들어 주었다. 이때 @Aspect 어노테이션으로 매우 편리하게 어드바이저를 만들 수 있다. 1. @Aspect @Aspect를 사용해도 중요한 것은 포인트컷과 어드바이스를 구성해야 한다. 해당 어노테이션은 이를 편리하게 도와주는 도구이다. 코드로서 보자! @Slf4j @Aspect public class LogTraceAspect { private final LogTrace logTrace; public LogTraceAspect(LogTrace logTrace) { this.logTrace = logTrace; } @Around("execution(* hello.proxy...

AOP 1편 [프록시 팩토리, 빈 후처리기]

인터페이스가 있는 경우에는 JDK 동적 프록시를 적용하고, 그렇지 않은 경우에는 CGLIB를 적용하려면 어떻게 해야할까?에 대한 해답을 스프링이 제공해 준다. 이 두 동적 프록시를 통합해줄 ProxyFactory라는 기술을 이용하자. 1. 프록시 팩토리 위 사진과 같은 역할을 하기 위해 어떤 것이 필요할까? 단연 InvocationHandler와 MethodInterceptor의 공통 된 로직을 작성해야 할 것이다. 이 공통된 로직을 advice라 하고 이 advice를 적용할지 말지 결정하는 녀석을 point cut이라 한다. 이 point cut 과 advice의 조합을 advisor라고 부른다. 즉 전체 흐름은 아래와 같을 것이다. 백문이불여일타! 코드를 작성해보자. 1.1 advice 코드 adv..

AOP 1편 [디자인 패턴-2, 동적 프록시]

이전 글에서 탬플릿 콜백 패턴으로 부가기능과 핵심 기능을 정말 잘 나누었지만 원본 코드(핵심 기능만 있던 코드)를 수정할 수 밖에 없는 상태였다. 이를 해결하기 위해선 프록시를 알아야 한다. 프록시에 대해 배울 겸 추가된 요구사항에 대해서도 배우자. 1. 특정 메서드에는 로그 기능을 사용하지 않을 것. 2. 다양한 케이스(i. 인터페이스 있는 구체 클래스 ii. 인터페이스 없는 구체 클래스 iii. 이전 두 방식은 수동 빈 등록을 사용할 것이고 마지막 방식은 컴포넌트 스캔을 적용한 클래스) 에 대해서도 만족해야 한다. 0. 프록시란? 컴퓨터 네트워크에서도 자주 다루 듯이 중간자 또는 대리자를 의미한다. client는 server에게 요청 하는 것이 아닌 proxy에게 요청을 하고 proxy가 server..

AOP 1편 [디자인 패턴 - 1]

[AOP의 모든 내용은 김영한님의 [스프링 핵심원리 - 고급편]의 내용을 공부하며 정리한 것입니다. 강의 링크는 하단에 있어요.] AOP는 aspect of programming이라는 의미로 관점 지향 프로그래밍이다. 이게 무엇이냐면, 많은 메서드에 공통된 로직을 넣어야 할때 해당 코드를 넣어버린 후에 나중에 로직이 조금 수정 된다면 이를 사용한 메서드 마다 수정해야 한다. 단순히 공통 로직을 클래스와 메서드로 만들어서 의존관계를 주입받아 호출할 수 는 있지만, 매서드 인자가 바뀐 다던지 아니면 공통된 로직이 한 10개 정도 되면 메서드마다 10개의 줄이 추가되야 한다. 정말 불상사.. 이런 방식은 SRP를 당당하게 위반한다. 이를 위해 AOP가 나왔다. 마치 코드를 위한 코드? 요구사항이 코드 추가인 ..