일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- @ControllerAdvice
- springboot
- Effective Java
- db
- @MockBean
- Proxy Patter
- 이펙티브 자바
- 디자인 패턴
- Service Locator 패턴
- NotBlank
- java
- Service Locator
- 트랜잭션
- Web
- deleteById
- FCM
- 플라이웨이트
- restTemplate
- Firebase
- Connection Pool
- @SpyBean
- Item04
- multi module
- @Valid
- 데이터베이스
- Spring Boot
- Effetive Java
- JPA
- SQL 삽입 공격
- NotEmpty
- Today
- Total
목록분류 전체보기 (64)
NoTimeForDawdling
![](http://i1.daumcdn.net/thumb/C150x150.fwebp.q85/?fname=https://blog.kakaocdn.net/dn/csQ1rn/btrQw2fbmom/gizj3AZgNLFpNvkq5NKqo0/img.png)
상황에 따라 ArrayList와 LinkedList를 적절히 활용한다면 더 좋은 효율성을 보여줄 수 있을 텐데요, 어떨 때 어떤 자료구조를 사용하면 좋을지 한번 알아보겠습니다. 구조 ArrayList와 LinkedList를 그림으로 보면 다음과 같습니다. ArrayList는 데이터들이 순서대로 쭉 늘어선 배열의 형식을 취하고 있습니다. LinkedList는 순서대로 늘어선 것이 아니라 자료의 주소 값으로 서로 연결되어 있는 구조를 하고 있습니다 ArrayList 동적 배열을 사용하여 요소를 저장합니다. 데이터를 저장하고 접근하는데 좋습니다. 특정 자료형들이 메모리 공간 상에서 연속적으로 이루어져 있습니다. 인덱스로 해당 원소에 접근할 수 있으며, 인덱스를 알고 있다면 O(1)의 시간 복잡도로 원소에 접근..
![](http://i1.daumcdn.net/thumb/C150x150.fwebp.q85/?fname=https://blog.kakaocdn.net/dn/R8lyF/btrfPWCVxh9/SrUKrdkzckusECfhoEbtDk/img.png)
최근에 비동기 처리에 대한 관심이 생겼다. Java를 활용한 비동기 처리에 대해 한번 공부해보고자 한다. Sync vs Async CompletableFuture를 공부하기에 앞서 Sync(동기)와 Async(비동기)에 대해 먼저 알아보자. 이번 포스팅에서 사용할 시나리오는 다음과 같다. 시나리오 카페에 있는 메뉴의 가격을 조회한다. 예를 들어 "iceAmericano"라는 이름의 메뉴를 조회하면 4100원이라고 응답을 해주는 기능이다. 클래스에서는 가격을 조회하는 메서드를 제공한다. 클라이언트는 해당 메서드를 호출할 때 커피의 이름을 파라미터로 넘겨주면 4100원이라는 데이터를 리턴받는다. 여기서 클라이언트는 메서드를 호출하는 곳이다. Sync 클라이언트에서 "iceAmericano"라는 메뉴를 조회하..
![](http://i1.daumcdn.net/thumb/C150x150.fwebp.q85/?fname=https://blog.kakaocdn.net/dn/dT05RV/btrfhdxyyb6/ZPKsy2Uw8G7LasvGMLxROk/img.png)
이전 포스팅에서 Device Token을 통해 FCM Push 메시지 보내는 방법에 대해 설명했었다. 이번에는 Topic이라는 개념을 통해 메시지를 보내는 방법에 대해 설명하고자 한다. 설명하기에 앞서 해당 포스팅(FCM Push 메시지 보내기)에 정리한 Firebase 관련 설정을 해줘야 한다. build.gradle Firebase 설정을 해줬다면 build.gradle에 다음 내용을 추가하자. 다음으로 FirebaseConfig를 작성하기에 앞서 FcmSubscribeService 코드를 작성했다. @Service public class FcmSubscribeService { public String subscribeToTopic(List tokens, String topic) { ApiFuture..
![](http://i1.daumcdn.net/thumb/C150x150.fwebp.q85/?fname=https://blog.kakaocdn.net/dn/JcsdX/btre33Pd6Fd/PJXEKkklOgYNZYQGlrATh0/img.png)
푸시 알림은 Server에서 유저의 device로 정보를 보내는 것을 말한다. 구글이 제공하는 Firebase Cloud Messaging(FCM)을 이용하면, 서버와 같은 외부에서 내가 소유한 앱이 설치된 기기로 1개 이상의 메시지를 전송할 수 있다. FCM은 완전히 무제한으로 무료 제공된다. 크로스 플랫폼을 지원하여 Android, iOS, Chrome 기기에 메시지를 전송할 수 있다. 이번 포스팅에서는 Spring Boot 기반 프로젝트에서 FCM을 이용한 메시지 전송 방법을 적어보려 한다. Firebase 설정 Firebase에서 앱 서버로 푸시를 보내려면 Access Token을 발급받아야 한다. 우선 Firebase 콘솔에 접속하여 메시지를 전송할 앱을 선택한다. 없다면 앱을 새로 만들어야 한..
![](http://i1.daumcdn.net/thumb/C150x150.fwebp.q85/?fname=https://blog.kakaocdn.net/dn/cvTucy/btreTH6l8Dp/aW2EiakNYaS2AHkgW7HpZK/img.png)
String String 클래스는 immutable(불변) 하기 때문에 String의 값은 한 번 생성되면 변경될 수 없다. String 클래스의 문자열을 저장하는 char[]를 보면 final로 선언되어있다는 것을 확인할 수 있다. 그렇기 때문에 한번 할당한 문자열에 대한 변경이 불가능하며, 문자열 연산이 많아질 때 계속해서 새로운 객체를 만들기 때문에, 오버해드가 발생하므로 성능이 떨어지는 단점이 있다. 반복적으로 문자열을 이어 붙이면 Heap영역에 참조를 잃은 문자열 객체가 계속해서 쌓이게 되고, 이는 GC에 대한 비용이 증가라는 단점을 낫게 된다. 하지만 이러한 불변성은 멀티스레드 환경에서 동기화를 신경 쓸 필요가 없다. 즉, Thread Safe하다. 또한, 단순하게 읽어가는 조회 연산에서는 타..
![](http://i1.daumcdn.net/thumb/C150x150.fwebp.q85/?fname=https://blog.kakaocdn.net/dn/pvl3Q/btrdrna2p40/9dBbX3o2DtKK6VPkS6kbP1/img.png)
최근에 토이 프로젝트를 진행하면서 멀티 모듈을 적용해봤다. 모듈은 다음과 같이 분리했다. core - 시스템의 핵심 도메인 기능을 제공하는 모듈 - Repository와 밀접한 중심 도메인을 다루는 계층 - 서비스에 대한 로직을 모름. common - 각 모듈의 공통된 기능을 제공하는 모듈 - common모듈은 다른 모듈에 대한 의존성이 없어야 한다. - ex) common exception, utill class web - api, service 관련 기능을 제공하는 모듈 event - event 처리 모듈 자 그럼 이제 모듈을 생성해주자. 모듈을 생성하려면 기존 프로젝트에서 New -> Module을 선택해서 생성하면 된다. 이후 Gradle 선택 -> Java -> 모듈명을 입력하면 끝난다. 모듈을..
![](http://i1.daumcdn.net/thumb/C150x150.fwebp.q85/?fname=https://blog.kakaocdn.net/dn/c00lTF/btrdqK4KYXp/o01laArMvnkIqoKF2VvoCk/img.png)
Spring Data JPA에서 제공하는 쿼리 메서드 기능으로 3가지가 있다. 메서드 이름으로 쿼리 생성 JPA NamedQuery 사용 @Query 어노테이션 사용 이 중에 메서드 이름으로 쿼리를 생성하는 방법을 알아보자. 메서드 이름으로 쿼리 생성이란? 메서드 이름을 분석해서 JPQL 쿼리를 실행하는 것을 의미한다. 똑똑한 Spring Data JPA가 메서드 이름을 분석해서 JPQL을 유추해서 생성하고 실행한다. public interface UserRepository extends Repository { List findByEmailAddressAndLastname(String emailAddress, String lastname); } 위 코드는 다음과 같은 쿼리를 생성한다. select u f..
데이터베이스에 특정 데이터가 언제 생성되었고, 마지막 수정 날짜는 언제인지 기록하는 것은 꽤나 중요하다. 그렇기 때문에 해당 데이터는 도메인마다 공통으로 존재하게 되고, 코드의 중복이 발생하기 마련이다. 이런 문제를 해결하기 위해 JPA는 Audit라는 기능을 제공하고 있는데, 이는 JPA에서 시간에 대한 값을 자동으로 넣어주는 기능이다. BaseEntity 생성 Auditing이 필요한 Entity에서 사용할 BaseEntity는 다음과 같이 정의해 줬다. @Getter @EntityListeners(AuditingEntityListener.class) @MappedSuperclass public abstract class BaseEntity { @CreatedDate @Column(updatabl..