Welcome to MikeDaDev's Blog – notes on Java, backend & system design.

Explore
MikeDaDev's Blog

#spring-boot

Things I've written about #spring-boot
  • Claude Code template cho Spring Boot: mổ xẻ repo của Piotr Mińkowski

    Repo claude-ai-spring-boot gói sẵn CLAUDE.md, 6 agent và 7 skill để Claude Code viết Spring Boot 4 theo đúng chuẩn. Bài này mở từng phần ra xem nó vận hành thế nào, rồi chạy thử code mẫu trong skill trên Spring Boot 4.1.1: chỗ nào compile không qua, chỗ nào Kubernetes sẽ âm thầm bỏ qua preStop hook, file quyền nào đi theo khi clone, và cách sửa trước khi đem về dùng cho team.

  • Resilience4j trong Spring Boot

    Một service downstream sập hoặc trả lời chậm rì thì làm sao để nó không kéo cả hệ thống microservices sập theo (cascading failure)? Bài này đi qua Resilience4j: Circuit Breaker với sliding window, Bulkhead để cô lập thread và RateLimiter, kèm cấu hình dùng được ngay.

  • Feature Flags với Unleash & Spring Boot

    Feature Flags với Unleash trong Spring Boot 3: 4 nhóm toggle theo cách chia của Pete Hodgson, cách Unleash đánh giá flag ngay trong bộ nhớ phía client và đồng bộ qua Server-Sent Events, chuyện MurmurHash3 chia user khi gradual rollout, và dùng Strategy Pattern để thoát khỏi đống if-else.

  • transactional outbox & idempotent consumer

    Xử lý bài toán Dual-Write cho đúng: Transactional Outbox với Debezium SMT, kỹ thuật SELECT FOR UPDATE SKIP LOCKED, vì sao Kafka transaction không cứu được bạn ở đây, và cách làm Idempotent Consumer chạy được trên production với RDBMS (kèm Redis làm lớp lọc nhanh).

  • Rate Limiting với Bucket4j trong Spring Boot

    Vì sao chỉ rate limit ở Nginx là chưa đủ? Mổ xẻ thuật toán Token Bucket, cách Bucket4j xử lý concurrency không cần lock, và cách dựng rate limiting phân tán với Redis trong Spring Boot để chạy production.

  • RestClient & Fluent API trong Spring Boot 3

    Vì sao RestTemplate bị cho vào chế độ bảo trì rồi sắp bị deprecate? Bài này nói về RestClient và JdbcClient, hai món mới theo kiểu Fluent API từ Spring Framework 6.1 / Spring Boot 3.2, viết gọn hơn, đọc dễ hơn và ít chỗ truyền nhầm tham số hơn.

  • GraalVM Native Image vs JVM JIT

    GraalVM Native Image khởi động trong vài chục tới vài trăm mili-giây, ăn RAM rất ít nên đang được dân Serverless và Kubernetes chuộng. Nhưng AOT có thay hẳn được HotSpot JIT không? Mổ xẻ kiến trúc, số đo minh hoạ, những thứ bạn buộc phải đánh đổi và các lựa chọn khác như Project Leyden.

  • jOOQ vs Hibernate JPA

    Vì sao nhiều team làm hệ thống tài chính cân nhắc jOOQ bên cạnh Hibernate? Chi phí ngầm của ORM, Type-safe SQL của jOOQ, những chỗ Hibernate 6 đã bắt kịp, và kiến trúc Hybrid dùng cả hai.

  • Spring Modulith

    Trước khi chia hệ thống thành Microservices và ôm theo đủ thứ đau đầu về network, distributed transaction, observability, thử xem Spring Modulith: giải pháp chính thức từ Spring để làm Modular Monolith với ranh giới module rõ ràng, tự kiểm tra phụ thuộc và event nội bộ giữa các module.

  • in aws / cloud

    amazon S3

    Ghi chú dùng Amazon S3 cho hệ thống lớn: Strong Read-After-Write Consistency là gì, dùng Presigned Multipart Upload để backend khỏi gánh băng thông, bảo mật với SSE-KMS và IRSA trên Kubernetes, và cái bẫy tốn tiền mang tên AbortIncompleteMultipartUpload.

  • multi-module spring boot

    Mổ xẻ kiến trúc Multi-Module Spring Boot cho production: chia module theo Hexagonal/Clean Architecture, tách riêng JPA/DataSource cho từng module, tránh mở connection pool tràn lan, xử lý cái bẫy bytea của JDBC PostgreSQL và dùng ArchUnit để giữ ranh giới module.

  • kiến trúc RabbitMQ

    Dựng RabbitMQ cho production cần biết gì: Erlang OTP/BEAM bên dưới, ghép nhiều Channel trên một TCP Connection, bỏ Mirrored Queues để chuyển sang Quorum Queues (Raft), không mất message nhờ Producer Confirms và Manual ACK, cùng Dead Letter Queue (DLQ) kèm retry exponential backoff.

  • strategy pattern

    Nhìn Strategy Pattern bằng con mắt Solution Architect: Strategy khác State và Template Method ở đâu, dùng Functional Interface của Java để khỏi đẻ ra cả đống class thừa, và dựng một Dynamic Promotion Engine bằng Spring Boot.

  • observer pattern

    Đi từ Observer Pattern kinh điển tới Event-Driven Architecture (EDA): vì sao java.util.Observable bị deprecate từ Java 9, quản lý transaction với @TransactionalEventListener AFTER_COMMIT, xử lý backpressure trong Reactive Streams và so sánh với Apache Kafka.

  • decorator pattern

    Decorator Pattern nhìn từ góc Solution Architect: vì sao kế thừa gây Class Explosion, Decorator thủ công khác gì Spring AOP Proxies (JDK vs CGLIB), bẫy Self-Invocation trong AOP và ví dụ Resilient Caching Decorator kèm những điểm cần lưu ý trước khi đem lên production.

  • factory pattern

    Nhìn lại Factory Pattern từ góc độ kiến trúc: vì sao Factory kiểu switch-case kinh điển lại vi phạm chính Open/Closed Principle, cách inject Map bean trong Spring Boot để bỏ hẳn if-else, Functional Factory với Java Supplier, và phân biệt Factory Method với Abstract Factory qua ví dụ multi-cloud.

  • singleton pattern

    Singleton Pattern nhìn kỹ hơn một chút: vì sao việc đảo lệnh của JIT và CPU buộc Double-Checked Locking phải có volatile, 4 cách phá Singleton (Reflection, Serialization, Clone, ClassLoader) và vì sao dự án Spring nên để IoC Container quản lý singleton.

  • spring security với jwt

    Spring Security kết hợp JWT (JSON Web Token) là cách phổ biến để bảo mật RESTful API. Thay vì stateful (Session/Cookie lưu trên server), xác thực chuyển sang stateless: mọi thông tin nằm trong token, nên hệ thống dễ scale hơn và đỡ tốn bộ nhớ trên server.

  • multi-module Spring Boot với Gradle

    Dựng Multi-Module Spring Boot 3 với Gradle hiện đại: bỏ anti-pattern subprojects/allprojects, dùng Convention Plugins để tái sử dụng cấu hình, quản lý dependency tập trung bằng Version Catalog (libs.versions.toml), hiểu compile avoidance giữa api và implementation, và xử lý xung đột bootJar vs jar.

  • hibernate ORM

    Hibernate ORM bên trong chạy thế nào: 4 trạng thái vòng đời của Entity (Transient, Persistent, Detached, Removed), Dirty Checking tự động qua Loaded Snapshots, First-Level vs Second-Level Cache, và cách tiết kiệm bộ nhớ với @Transactional(readOnly = true).

  • custom annotations trong java

    Annotation trong Java chạy thế nào bên trong JVM: bytecode attribute, dynamic proxy, meta-annotation của Spring (@AliasFor), rồi tự viết một custom annotation dùng Spring AOP và SpEL để làm rate limiting phân tán dùng được cho production.

  • Spring Security annotations

    Kiến trúc bảo mật của Spring Security: hai lớp phòng thủ FilterChain và AOP Method Security, SpEL trong @PreAuthorize, bẫy Side-Effect của @PostAuthorize, vấn đề hiệu năng của @PostFilter và cách thiết lập Role Hierarchy cho production.

  • spring profiles và externalized config

    Quản lý cấu hình trong Spring Boot cho bài bản: nguyên tắc 12-Factor Config, thứ tự ưu tiên giữa các PropertySource, spring.config.import (Spring Boot 2.4+), kết hợp HashiCorp Vault & Kubernetes ConfigMaps, và reload nóng với @RefreshScope.

  • Spring Boot Auto-configuration

    Spring Boot Auto-Configuration chạy thế nào bên dưới: AutoConfigurationImportSelector, bộ lọc sớm dựa trên metadata sinh lúc build, ASM đọc annotation mà không nạp class, thứ tự của DeferredImportSelector, chuyển từ spring.factories sang AutoConfiguration.imports, và cách viết một Custom Starter dùng được trên production.

  • @ManyToMany trong JPA

    @ManyToMany trong JPA/Hibernate hoạt động ra sao: vì sao Hibernate xóa sạch bảng nối rồi insert lại (Write Amplification), vì sao không thêm được thuộc tính phụ (metadata), và cách làm dùng được trên production: tách thành hai @OneToMany qua Explicit Join Entity với @EmbeddedId và @MapsId.

  • @OneToMany & @ManyToOne trong JPA

    Mấy cái bẫy hay gặp với @OneToMany và @ManyToOne trong JPA/Hibernate: EAGER ngầm, N+1 query và cách xử lý bằng EntityGraph hay BatchSize, lỗi MultipleBagFetchException do Cartesian Product, và StackOverflowError vì lỡ dùng Lombok @Data.

  • Spring IoC & Dependency Injection

    Mổ xẻ bên trong Spring IoC Container: DIP, IoC và DI khác nhau ra sao, vòng đời của một bean trong ApplicationContext, cách Spring gỡ circular dependency bằng cache 3 tầng (three-level cache), và vì sao field injection với @Autowired bị loại khỏi code enterprise.

  • java records

    Hiểu Java Records cho đúng: "transparent carrier" nghĩa là gì, vì sao serialization của Record an toàn hơn, Pattern Matching với Sealed Types, Shallow vs Deep Immutability và mấy cái bẫy khi đem Record dùng với JPA / Hibernate.