| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 | 29 |
| 30 |
- lombok
- nestjs
- factory
- Google OAuth
- 일급 객체
- OAuth 2.0
- 일급 컬렉션
- Volatile
- builder
- spring security
- middleware
- java
- Dependency Injection
- Spring
- synchronized
- Today
- Total
목록전체 글 (191)
HJW's IT Blog
들어가며HTTP Post 메서드는 기본적으로 멱등성(idempotence)이 보장되지 않는 메서드 이다. 여기서 멱등성이란 같은 요청이 여러번 반복되어 실행되더라도 결과가 변하지 않는 속성을 의미한다.예를 들어 클라이언트가 웹 양식을 서버에 제출하고, 서버는 이에 대한 응답을 보냈다고 가정하자. 이 상태에서 클라이언트가 웹페이지를 새로고침 한다면 어떻게 될까?바로 전과 같은 양식으로 동일한 데이터를 서버로 보낸다위와 같은 상황이 발생하면, 동일한 개시글 업로드, 중복된 결재 등의 문제를 야기할 수 있다.PRG Pattern 이란?PRG 는 Post / Redirect / Get 의 약어이다. 위와 같은 상황에서 데이터 중복 문제를 방지하기 위한 디자인 패턴으로 흐름은 다음과 같다.사용자가 POST 요청을..
들어가며현대 소프트웨어 개발에서 멀티스레드 프로그래밍은 빠질 수 없는 핵심 주제중 하나이다. 여러 스레드가 하나의 프로그램을 구성하여 조작할 때, 여러 이점이 있지만, 동시성 문제, 일관성 등의 문제또한 야기한다.본격적으로 Volatile 에 대해 이야기 하기 전, 변수 가시성 에 대해 이해하고 넘어가야 한다. 변수 가시성 문제 란 하나의 스레드가 특정 변수의 값을 변경 했을 때, 다른 스레드에서 그 변경 사항을 즉각적으로 확인하지 못하는 상황을 의미한다. 다음 코드를 한번 보자class SharedResource { private boolean flag = false; public void setFlagTrue(){ this.flag = true; } public void waitForFlag()..
들어가며빌더 패턴은 왜 써야 할까? 이 질문은 빌더 패턴을 공부하는 과정에서 끊임없이 던졌던 핵심 의문이었다. 개발자로서 중요한 덕목 중 하나는 무언가를 선택하고 사용할 때 그에 대한 명확한 “이유”를 가져야 한다는 것이다. 단순히 “빌더 패턴이 좋다고 하니까”라는 이유로 사용한다면, 나중에 누군가 “빌더 패턴을 왜 사용하셨나요?”라고 물었을 때 설득력 있는 대답을 하기 어려울 것이다.0. 빌더 패턴의 배경1.1 점층적 생성자 패턴의 한계점층적 생성자 패턴은 객체 생성을 위한 전통적인 방식이다. 이 패턴의 구조는 다음과 같다.public class Pizza { private final String dough; // 필수 private final String sauce; //..
들어가며..디스코드 시스템을 설계하고 구현하는 도중, 각 서버의 Channel 설계에 대해 고민을 하게 되었다.처음 “Channel”을 설계할 때, 이 엔티티(혹은 객체) 하나에 음성 채널과 채팅 채널을 모두 담을 것인지가 가장 큰 고민이었다.음성 채널: 음성 통화를 위한 기능이 필요하고, 채팅 메시지는 필요 없다.채팅 채널: 채팅 메시지가 필수이고, 음성 통화는 필요 없다.만약 둘을 하나의 부모 클래스로 묶는다면, 잘못하면 음성 채널에 채팅 기능이 들어가야 하고 채팅 채널에서 음성 채팅을 지원해야 하는 상황이 발생할 수도 있다. “서버의 채널”이라는 점에서는 같지만, 내부 동작과 필요한 기능이 전혀 다르기 때문이다.이러한 고민 속에서 나온 아이디어가 ChannelBehavior라는 인터페이스를 둬서, ..
들어가며DispatcherServlet은 Spring의 핵심 요소중 하나이다. DispatcherServlet은 Spring의 프론트 컨트롤러로서, 모든 웹 요청의 진입점 역할을 담당한다. HTTP 요청을 가장 먼저 받아 적절한 컨트롤러로 위임하는 것이 주 역할이다. DispatcherServlet과 Spring의 동작 과정을 잘 이해하기 위해선 프론트 컨트롤러 패턴의 개념과 장점에 대해 확실하게 짚고 넘어가야 한다.1. 초기 웹 어플리케이션 개발의 문제점초기 웹 어플리케이션 개발에선, 각 요청에 대해 개별적으로 처리하는 서블릿 혹은 JSP 를 작성하는 것이 일반적이었다. 한번 JSP 코드를 한번 보고 넘어가자. members = memberRepository.findAll();%>메인 i..
1. 상속은 무엇인가?Inheritance 는 간단히 말해 부모 클래스의 기능과 속성을 자식 클래스가 물려받는 관계이다. 예를 들어 다음과 같은 상황이 상속이다.class Animal{ void eat() { System.out.println("Eating..."); }}public class Cat extends Animal{ public void meow(){ System.out.println("meow"); }}public class Main { public static void main(String[] args) { Cat cat = new Cat(); cat.eat(); cat.meow(); }} 이와 같이 Cat 에는 분..
들어가며 SRP, 어디까지 적용되어야 할까.. 는 코드를 작성할 때 항상 고민하던 부분 같다. 과도하게 분리하게 되면 오히려 복잡도와 가독성이 떨어지는 것 같고, 분리를 하지 않는다면 하나의 메소드 혹은 클래스가 너무 많은 책임을 지는 것 같았다.예를 들어 UserManager 라는 클래스가 있다면. 이 클래스의 책임 범위는 어디까지 일까?사용자에 관련된 모든 기능?간단한 CRUD?Login, Logout 까지만?명확한 답을 내리기 힘든 질문 인 것 같다. 첫생각 public class UserManager { public void createUser() { ... } public void updateUser() { ... } public void deleteUser() { ... ..
빈 생명주기 콜백빈 생명주기 콜백 시작어플개발을 하다 보면, 어플리케이션 시작 시점에 특정 서비스나 리소스를 준비하거나, 연결해둔 뒤에 어플리케이션 종료 시점에 이를 깔끔하게 정리하는 로직이 필요한 경우가 있다.예를 들어DB Connection Pool 연결 : 어플리케이션 구동 시점에 미리 연결 풀을 구성해두면 빠른 DB 연동이 가능하다외부 서비스와의 Socket 연결 : 초기에 연결을 맺어 두었다면, 어플리케이션 종료 전에 연결을 해제해야 정상적인 종료가 가능하다.이와 같이 시작할때, 준비, 끝날때 정리 는 매우 흔한 요구사항이다. 그렇다면 우리는 스프링 빈이 언제 준비 되는지와, 어떤 시점에 초기화 / 정리 로직을 호출할 수 있는지를 명확하게 알아야다음과 같은 예시를 보자 public class N..
컴포넌트 스캔 / Dependency Injection컴포넌트 스캔과 의존관계 자동 주입이전 포스팅 까지는, Spring Bean 등록시, @Bean 을 사용해 설정 정보에 직접 등록 해 주었다. 하지만, 프로젝트 규모가 커질 수록, 일일이 등록하기도 힘들고, 누락하는 문제도 발생한다. 이번 포스팅에선, 자동으로 Spring Bean 을 등록하는 방법에 대해 알아보자우선, AutoAppConfig.java 파일을 생성.package hello.core;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframew..
📔 웹 어플리케이션과 싱글톤스프링은 태생이 기업용 온라인 서비스 기술을 지원하기 위해 탄생했다. 그렇기에 대부분의 스프링 어플리케이션은 웹 어플리케이션이다. 웹 어플리케이션의 특징은, 보통 여러 고객이 동시 요청을 보낸다는 점이다. 그렇다면 어플리케이션이 커지고, 트레픽이 많아질 수록, 객체 생성 비용과 메모리 사용량은 증가하게 되고, 많은 리소스를 소모한다는 뜻이다. 다음은, 스프링이 없는 순수한 DI 컨테이너 테스트 예시이다. public class SingletonTest { @Test @DisplayName("스프링 없는 순수 DI 컨테이너") void pureContainer(){ AppConfig appConfig = new AppConfig(); ..