Command Palette

Search for a command to run...

Bài viết trong series "Advanced Spring Boot"

14 bài viết

[Advanced Spring Boot] Tự viết auto-configuration và starter cho Spring Boot

Tự xây và phát hành một starter Spring Boot 4.1.1 thật: ba Gradle project và quy tắc đặt tên x-spring-boot-starter, class @AutoConfiguration với @ConditionalOnMissingBean và @ConditionalOnProperty, đăng ký trong AutoConfiguration.imports, sắp thứ tự bằng before/after so với một auto-configuration của Boot, record @ConfigurationProperties có validation cùng file spring-configuration-metadata.json sinh ra tự động, một SpringBootCondition tự viết với message ConditionOutcome xuất hiện trong report, năm test ApplicationContextRunner kể cả FilteredClassLoader, publish lên mavenLocal rồi dùng thật, và một FailureAnalyzer cho lỗi cấu hình.

[Advanced Spring Boot] Mở rộng container của Spring: BeanFactoryPostProcessor, BeanPostProcessor và Aware

Các extension point của container trong Spring Boot 4.1.1, trace qua một lần startup: bảng đánh số từ EnvironmentPostProcessor tới các runner, cách đăng ký từng callback trong Boot 4 và lý do context.initializer.classes không còn tác dụng, BeanFactoryPostProcessor so với BeanDefinitionRegistryPostProcessor, một BeanPostProcessor trả về JDK dynamic proxy, cái bẫy "not eligible for getting processed by all BeanPostProcessors" làm mất transaction trong im lặng, chain post-processor đo được cho thấy @Order bị bỏ qua, các interface Aware đáng biết, và exception trong ApplicationRunner ảnh hưởng thế nào tới exit code.

[Advanced Spring Boot] Spring AOP: proxy JDK và CGLIB, aspect và lỗi self-invocation

Spring AOP trên Spring Boot 4.1.1: spring-boot-starter-aop đã biến mất khỏi BOM và spring-boot-starter-aspectj thay thế nó, JDK dynamic proxy so với CGLIB subclass kèm tên class thật, ClassCastException mà JDK proxy gây ra, class final ném AopConfigException, method final âm thầm NPE vì Objenesis bỏ qua constructor, các pointcut designator đáng dùng, thứ tự đo được của cả năm loại advice trên hai nhánh, @Order giữa các aspect, lỗi self-invocation nằm dưới @Transactional và @Async cùng ba cách sửa được so sánh, chi phí nanosecond của một lời gọi qua proxy, và Advised#getAdvisors để debug.

[Advanced Spring Boot] Spring Events: ApplicationEventPublisher, @EventListener và @TransactionalEventListener

Spring event trên Spring Boot 4.1.1: publish một record qua ApplicationEventPublisher và lớp bọc PayloadApplicationEvent, bằng chứng @EventListener chạy trên thread và transaction của caller, @Order cùng condition SpEL, listener trả về event khác, vì sao listener cho generic OrderEvent<Product> không bao giờ nhận được gì nếu thiếu ResolvableTypeProvider, listener throw exception khi sync và khi @Async, đủ bốn phase của @TransactionalEventListener với log của từng lần chạy, fallbackExecution, cái bẫy ghi database trong AFTER_COMMIT làm mất row và REQUIRES_NEW cứu nó, @Async so với applicationEventMulticaster async, và chỗ event in-process hết là một cơ chế đáng tin.

[Advanced Spring Boot] Tối ưu JPA: phát hiện N+1, batch fetching, projection và batch insert

Tối ưu hiệu năng JPA trên Spring Boot 4.1.1 và PostgreSQL: đếm SQL cho mỗi request bằng StatementInspector và log session metrics của Hibernate 7, integration test fail khi có N+1, @BatchSize và default_batch_fetch_size với array parameter = any(?) mà PostgreSQL nhận, FetchMode.SUBSELECT đọc 801 row cho một trang 20 order, mẫu hai query để phân trang parent cùng children, projection dạng closed, open, record, dynamic và native cùng những gì chúng để lại trong persistence context, và batch insert khi IDENTITY gửi 10,000 statement còn SEQUENCE pooled cùng batch_size, order_inserts và reWriteBatchedInserts chỉ gửi 600.

[Advanced Spring Boot] Transaction chuyên sâu trong Spring: propagation, isolation level và rollback rules

Propagation, isolation level và rollback rules của Spring trên Spring Boot 4.1.1 với PostgreSQL: đủ bảy propagation với log JpaTransactionManager và backend pid, deadlock connection pool do REQUIRES_NEW kèm số đo HikariCP, vì sao NESTED lỗi với JpaTransactionManager nhưng chạy bằng savepoint với JdbcTransactionManager, non-repeatable read, lost update và write skew ở từng isolation level, SQLSTATE 40001 thành CannotAcquireLockException, retry đúng chỗ quanh transaction, readOnly ở tầng JDBC, PostgreSQL và Hibernate, validateExistingTransaction, rollbackOn ALL_EXCEPTIONS và thứ thực sự áp dụng @Transactional(timeout).