본문 바로 가기

전체 글28

스프링 직접 구현하기 #3: DispatcherServlet 구현 들어가며이번에는 스프링 MVC의 핵심 엔진, DispatcherServlet의 기능을 직접 구현해보겠습니다. 처음부터 너무 복잡하게 만들기보다는, 가장 기본적인 기능부터 차근차근 만들어보는 것을 목표로 삼았어요. 실제 HTTP 통신 대신, 콘솔 입출력을 통해 기능을 모의로 구현해볼 겁니다. 요청은 다음과 같은 간단한 형식으로 정의했어요.요청 형식: /{path} {body} (예: /climb Tiger1)이 요청을 처리할 컨트롤러는 두 가지 스타일을 지원하도록 구상했습니다.@RequestMapping 어노테이션 스타일 컨트롤러:@Component@Controllerpublic class TigerRunController { @RequestMapping("/run") public String ..
[자바] AtomicInteger: incrementAndGet 구체적인 동작방식 들어가며AtomicInteger 클래스는 원자적 연산으로 자바의 동시성 문제를 해결하는 방안 중 하나입니다. AtomicInteger 클래스의 incrementAndGet() 메소드에 대해 자세히 알아보도록 하자.환경- 아키텍쳐: x86- os: linux- JDK17AtomicIntegerAtomicInteger 클래스에 대해 미리 설명해 둘 정보가 있다. private static final Unsafe U = Unsafe.getUnsafe(); private static final long VALUE = U.objectFieldOffset(AtomicInteger.class, "value"); private volatile int value;AtomicInteger 는 ..
[자바] HashMap 파헤치기: put() 메소드는 어떻게 동작할까? 들어가며이번 글에서는 HashMap의 put() 메소드의 내부 구현을 단계별로 살펴보며 HashMap이 어떻게 동작하는지 알아보겠습니다.HashMap의 기본 구조와 핵심 용어HashMap 클래스의 주석에는 성능에 영향을 미치는 두 가지 중요한 매개변수가 언급됩니다: 바로 초기 용량(initial capacity)과 로드 팩터(load factor)입니다.An instance of HashMap has two parameters that affect its performance: initial capacity and load factor. The capacity is the number of buckets in the hash table, and the initial capacity is simply th..
[Linux] 페이지 테이블 구조 리눅스에서 페이지 테이블이 어떻게 구성되어 있는지 알아보자.환경리눅스 커널 5.15 버전, x86_64 기준🌵 페이지 테이블 구조테이블 매핑 방식은 4가지가 존재한다.직접 매핑연관 매핑집합-연관 매핑역매핑해시형 테이블 구조그중, 리눅스는 직접 매핑방식 중, 계층적 페이지 테이블을 사용한다.계층적 페이지 테이블은 아래 그림을 보면 직관적으로 이해 할 수 있다.64bit 를 나누어서, 각각을 offset 으로 사용하는 방식이다.리눅스에서는 디폴트로 다음과 같이 4단계로 페이지 테이블을 구성한다.PGD (Page Global Directory)PUD (Page Upper Directory)PMD (Page Middle Directory)PTE (Page Table Entry)pgtable_64_types.h..
[MySQL, Spring] 간단한 로컬 Replication 세팅 가이드 들어가며MySQL 8.0과 Spring Boot 3를 이용하여 Master-Slave Replication 환경을 구축하고, Spring의 트랜잭션 특성에 따라 적절한 데이터베이스로 라우팅하는 방법을 설명합니다.목표MySQL 8.0을 이용하여 Master 1대와 Slave 2대로 구성된 Replication 환경 구축Spring Boot에서 읽기 전용 트랜잭션(@Transactional(readOnly = true))은 Slave DB에 접근쓰기 트랜잭션(기본 @Transactional)은 Master DB에 접근하도록 설정Master DB: 쓰기 작업 전담 (mysql_three, 포트 3308)Slave DB: 읽기 작업 담당 (mysql_one, mysql_two, 포트 3306, 3307)읽기 작..
Hibernate의 객체 매핑 성능 비밀: 내부 동작 원리 파헤치기 들어가며JPA를 사용하다 보면 일반적인 JDBC에 비해 객체 매핑에 따른 오버헤드를 걱정하게 됩니다. 그러나 실제 테스트 결과 JpaCursorItemReader가 JdbcCursorItemReader보다 2~5배 빠른 결과를 보였습니다. 이 의외의 결과가 단순히 로깅 문제였다는 것을 나중에 알게 되었지만, 이 과정에서 Hibernate의 객체 매핑 메커니즘을 자세히 살펴볼 기회가 생겼습니다.이 글에서는 Hibernate가 어떻게 DB 결과를 자바 객체로 효율적으로 매핑하는지, 그 내부 동작 원리를 살펴보겠습니다. 실행 환경- JDK 17- Hibernate 6.6 📌 TL;DR (요약)JPA의 객체 매핑은 느릴 거라 생각했지만, Hibernate는 실제로 빠르게 동작한다.그 이유는 Hibernate가..
JPA의 @Transactional(readOnly = true) 동작 들어가며스프링과 JPA를 사용할 때 @Transactional(readOnly = true) 설정이 실제로 어떤 동작을 수행하는지 내부 코드 분석을 통해 알아보았습니다.실행환경- Hibernate 6.6- Spring Framework 6.2.6📌 TL;DR (요약)✅ 데이터베이스에 읽기 전용 트랜잭션임을 명시적으로 알립니다✅ 트랜잭션이 종료될 때 영속성 컨텍스트의 변경사항을 flush하지 않습니다🍖 데이터베이스에 읽기 전용 트랜잭션 알림JpaTransactionManager의 doBegin 메소드를 살펴보면:protected void doBegin(Object transaction, TransactionDefinition definition) { ... txObject.setReadOnl..
스프링 직접 구현하기 #2: 생성자 주입 들어가며Spring Framework의 핵심 기능인 의존성 주입(DI)을 직접 구현하는 두번째 편입니다. 이전 글에서는 필드 주입을 구현했고, 이번에는 setter 주입과 가장 권장되는 방식인 생성자 주입을 구현해보겠습니다. 생성자 주입은 다른 주입 방식들과 달리 객체 생성 시점에 의존성이 주입되어야 한다는 특징이 있습니다. 이로 인해 구현 난이도가 높아지지만, 객체의 불변성과 필수 의존성을 보장할 수 있다는 장점이 있습니다. 특히 순환 의존성 문제를 해결하기 위해 위상 정렬 알고리즘을 활용한 점이 이번 구현의 핵심입니다.🍠 Setter 주입생성자 주입을 다루기 전에, 먼저 구현한 setter 주입 코드를 간단히 살펴보겠습니다.private void injectBySetter() { for (Cl..