JAVA(16)
-
스프링 자동설정과 @Profile
최근 @Profile 이 어떻게 작동하는지에 대한 설명을 요청받았다. 무지성 구글링으로 갖다 쓴 것이라 당연히 대답하지 못했다. '이 어노테이션을 쓰면 알아서 빈 등록을 해주는구나' 정도로만 이해하고 사용했다. 사용하는 모든 기술의 코어를 파악하는 것은 현실적으로 어렵겠지만... 대략적인 그림은 그릴 수 있어야하지 않겠는가....! 질문받은 김에 @SpringBootApplication 에 대해서 조금 공부해보기로 했다. 허를 찌르는 질문 덕분에 또 관련 정보를 찾아보며 성장하는 계기가 되었다. 시작! 우선 SpringBoot 어플리케이션의 메인함수에 붙어있는 어노테이션을 살펴봅시다 @SpringBootApplication public class TempApplication { public static ..
2022.10.26 -
[Spring] LocalDateTime response가 array 형식으로 반환될 때
개인 프로젝트를 진행중입니다. API를 열심히 만들고, 여러 기능을 적용하면서 프로젝트를 확장중인 그 때였습니다. 성능 테스트를 위해 nGrinder groovy 스크립트를 작성하고 있었는데, 서버에서 LocalDateTime 형식의 변수가 이상한 형태로 반환됩니다. 클라이언트분과 협의해서 잘 파싱하면 작동에 문제는 없겠지만, api 명세서에 써놓아 예상한대로 작동이 되지 않으니 참 답답했습니다. 그러다, 정신적 지주 루이와 쿠킴이 도움의 손길을 내밉니다... https://velog.io/@godkimchichi/Spring-Boot-json%EC%97%90%EC%84%9C-LocalDateTime%EC%9D%B4-Array%EB%A1%9C-%EB%82%98%EC%98%AC-%EB%95%8C [Spri..
2022.08.22 -
[Spring] 싱글톤 빈이 동시 요청을 처리하는 방법
이 글은 'baeldung - How Does the Spring Singleton Bean Serve Concurrent Requests?' 를 보고 번역, 학습한 내용을 정리한 글입니다. 1. 개요 싱글톤 스코프로 생성된 스프링 빈이 동시에 들어오는 여러 요청을 처리하기 위해 보이지 않는 곳에서 어떻게 작동하는지 맛볼 것입니다. 또한 Java가 Bean 인스턴스를 메모리에 적재하는 방법과 이에 대한 동시 액세스를 처리하는 방법을 이해해봅시다 ^~^ 2. 스프링 빈과 자바 힙메모리 Java 힙 메모리는 애플리케이션 내에서 실행 중인 모든 스레드가 액세스할 수 있는 전역 공유 메모리입니다. Spring 컨테이너가 싱글톤 스코프의 빈을 생성할 때 빈은 힙에 올라갑니다. 스프링의 방식대로라면, 모든 스레드가..
2022.08.11 -
[Spring + Redis] 오류 org.springframework.data.redis.serializer.SerializationException: Cannot deserialize;
레디스의 scan 명령을 사용해서 키 목록을 조회하는 메서드를 만들고 있었습니다. 그런데, 계속 org.springframework.data.redis.serializer.SerializationException: Cannot deserialize; 오류가 발생합니다. 코드는 이렇습니다. @Scheduled(fixedRate = scheduledIncreaseSeconds, timeUnit = TimeUnit.SECONDS) public void scheduledIncreasePostHitCounts() { log.debug("스케줄 조회수 업데이트 태스크 {}", LocalDateTime.now()); // 리스트에 존재하는 키들 빼와서 update쿼리 날리기 ScanOp..
2022.07.29 -
[Spring + Redis] 레디스로 게시글 조회수 중복 카운팅 검증하기
개인 프로젝트로 간단한 게시판을 만들고 있습니다. 누구나 하는 주제라서 쉽게 생각하고 덤볐다가 아주 고생하고 있습니다. ㅎㅎ 작성한 기능 중, 게시글을 조회하면 조회수가 하나 올라가는 기능이 있습니다. public PostResponse findOne(Long postId) { Post post = postRepository.findByIdWithUser(postId). orElseThrow(() -> new IllegalArgumentException("해당하는 postId가 없습니다. 잘못된 입력")); int recommendCount = postRecommendRepository.countByPostId(postId); post.increaseHitCount(); List comments = co..
2022.07.27 -
ifPresent() 메서드로 Optional 처리하기
초보자 삽질 귀여움주의;; 도움 안됨주의;; 프로젝트 진행 중, DB에서 단건조회를 하고 Optional로 감싸져서 반환되는 값을 처리하고 있었다.. 게시글 추천 기능을 구현하려고 user_id 속성과 post_id 속성이 복합적으로 유니크하게 존재해야 했는데, 테이블 상에서 묶어서 unique로 관리하는 것은 뭔가 맘에 들지 않았다. 그래서 id속성을 따로 만들고 개발자가 수작업으로 데이터 정합성을 관리하려고 했다. 추천_테이블 코드: @Repository public interface PostRecommendRepository extends JpaRepository { @Query("select pr from PostRecommend pr where pr.user.userId=:userId and p..
2022.07.22 -
인스턴스화를 막기 위한 private 생성자
이 글은 'EFFECTIVE JAVA 3/E'를 보고 학습한 내용을 정리한 글입니다. 이펙티브 자바를 읽기 시작한지 이틀이 지났다. 명성대로 악명대로 생각보다 어려운 내용이 많다. JAVA 기초가 부족한 것이기도 하겠지만, 어려운 용어가 섞여서 등장하니 읽기가 너무 힘든 것도 조금은 있다. 그래도, 언젠가는 다 읽어야 하는 책이니 조금씩 시도하며 잊지 않고 자바 현지인이 되기 위해 노력해야겠다! 인스턴스화를 막으려거든 private 생성자를 사용하라 프로그램 개발을 하다보면 정적 메서드와 정적 필드만 담은 클래스가 생기는 경우가 있다. 내 경우는 InputView나 OutputView 같은 뷰 단의 로직을 처리하는 클래스라든지, 단순히 할인같은 계산을 담당하는 클래스가 이 경우에 속하는 것 같다. 이처럼..
2022.05.18 -
[Spring + DB] 트랜잭션과 스프링
1. 트랜잭션 [ 트랜잭션이란? ] 트랜잭션은 작업의 완전성을 보장해준다. 논리적인 작업 셋을 모두 완벽하게 처리하거나, 모두 처리하지 못할 경우에는 본래 상태로 복구하는 기능이다. 즉, 작업의 일부만 적용되는 현상(Partial update)이 존재하지 않게 해준다. 트랜잭션에 쿼리가 여러개 조합되었을 때만 의미있는 것은 아니다. 단일 쿼리도 트랜잭션으로 묶었을 때에도 전부 적용되거나 아무것도 적용되지 않는 결과를 보장해주는 것일 뿐이다. MySQL의 기본 스토리지 엔진은 InnoDB인데, 해당 엔진은 쿼리 중 일부라도 오류가 발생하면 전체를 원 상태로 만든다는 트랜잭션의 원칙대로 아래 insert 문을 실행할 때 롤백된다. (PK 중복) 결과적으로 테이블은 여전히 비어있게 된다. create tabl..
2022.05.13 -
[SPRING] 인프런 스프링 기본편 강의 공부기록. 下 (완)
의존관계 자동 주입 크게 4가지로 분류한다 생성자 주입 수정자 주입(setter) 필드 주입 일반 메서드 주입 생성자 주입 : @Component public class OrderServiceImpl implements OrderService { private final MemberRepository memberRepository; private final DiscountPolicy discountPolicy; @Autowired public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) { this.memberRepository = memberRepository; this.discountPolicy =..
2022.03.07 -
[SPRING] 인프런 스프링 기본편 강의 공부기록. 中
IoC, DI, 컨테이너 IoC(Inversion of Control) = 제어의 역전 기존에는 클라이언트가 구현 객체를 선택해서 생성하고 연결하고 실행했다. 이제는 AppConfig이 제어 흐름을 가져가서 의존성을 주입한다. 프레임워크 vs 라이브러리 프레임워크가 내가 작성한 코드를 제어하고, 대신 실행하면 그것은 프레임워크가 맞다. (JUnit) 반면에 내가 작성한 코드가 직접 제어의 흐름을 담당한다면 그것은 프레임워크가 아니라 라이브러리다. DI(Dependency Injection) = 의존관계 주입 DI가 잘 되어있는 코드는 import 코드만 보고도 의존관계를 쉽게 파악할 수 있다. (실행하지 않아도 분석이 가능) 패키지 상단 우클릭 - Diagrams - Show Diagram... 클래스 ..
2022.03.03