Tổng hợp 117 câu hỏi phỏng vấn Spring & Spring Boot kèm đáp án chi tiết, song ngữ Việt–Anh — sắp xếp từ cơ bản đến nâng cao. Ôn luyện miễn phí, tự động lưu tiến độ.
Spring Boot là framework tạo app Java/Spring nhanh, ít cấu hình, dựng trên Spring Framework để bỏ phần lớn XML và boilerplate. Gồm 3 phần chính: 1. Auto-configuration — tự cấu hình theo dependency có sẵn (thêm Tomcat → tự set up web server). 2.…
DI: dependency được cung cấp từ bên ngoài thay vì object tự new → giảm coupling, tăng testability (mock được khi test). Thay vì khởi tạo cứng new UserRepository() bên trong class, constructor nhận sẵn UserRepository từ ngoài — class chỉ khai báo cần gì,…
@Autowired bật tự động inject — Spring resolve và inject bean phù hợp. Đặt được trên constructor, setter, field. Resolve mặc định by type; nhiều bean cùng type → ambiguity, fix bằng @Qualifier("beanName") tại điểm inject hoặc @Primary trên bean mặc định. Dependency optional: @Autowired(required…
@Component @Bean --------- Đặt ở Class Method trong @Configuration Tạo bean Spring new qua default constructor Method return object Kiểm soát init Hạn chế Linh hoạt — logic tuỳ ý Discovery Component scan Khai báo tường minh Dùng @Bean (method trong @Configuration return object) cho:…
Config externalize settings ra ngoài code — giá trị theo môi trường (DB URL, port, log level...) đổi mà không rebuild. Hai format: (application.properties là dạng phẳng: server.port=8080, spring.datasource.url=....) Đọc trong code: @Value("${server.port}") cho 1 property; @ConfigurationProperties(prefix = "app") bind cả nhóm property vào record/class…
Actuator cung cấp endpoint production-ready expose thông tin app qua HTTP/JMX — không cần viết code monitoring. Thêm starter spring-boot-starter-actuator, chọn endpoint expose qua management.endpoints.web.exposure.include: health, metrics, info, prometheus. Endpoint chính: - /actuator/health — liveness/readiness probe (Kubernetes). - /actuator/metrics — CPU, memory, HTTP latency. -…
Spring Data JPA là abstraction trên JPA — khai báo interface, Spring sinh implementation tự động. @Repository: đánh dấu data-access component + tự chuyển đổi exception DB (SQLException) → Spring DataAccessException (unchecked, đồng nhất giữa các DB). JpaRepository đã có @Repository ngầm. Lợi ích: ít…
@Transactional — declarative transaction: Spring tự begin → commit → rollback, không cần connection.commit() thủ công. Mọi thao tác DB trong method chạy trong 1 transaction — bất kỳ bước nào throw exception → rollback toàn bộ (vd placeOrder gồm save order → trừ kho…
readOnly = true là hint cho transaction, không phải enforcement cứng. Tác dụng: 1. Hibernate tắt dirty checking — không snapshot entity → giảm memory + CPU. 2. Flush mode = MANUAL — không auto-flush. 3. DB có thể optimize — route sang read replica,…
Mono<T — publisher phát 0 hoặc 1 phần tử (như Optional async). Flux<T — publisher phát 0..N phần tử (như Stream async, có thể vô tận). Cả 2 lazy — chỉ chạy khi có subscriber. Backpressure: consumer báo producer "chỉ nhận X item/giây" → tránh…
@SpringBootApplication là meta-annotation gộp 3 annotation hay dùng nhất: Annotation Tác dụng ------ @Configuration Class là nguồn bean definition @EnableAutoConfiguration Bật auto-configuration @ComponentScan Scan component từ package hiện tại trở xuống Dùng: đặt trên class main (chạy SpringApplication.run(App.class, args)) ở root package để @ComponentScan quét…
Auto-configuration tự configure bean dựa trên dependency trong classpath — không cần khai báo thủ công. Cơ chế: 1. @EnableAutoConfiguration scan file META-INF/spring/...AutoConfiguration.imports (Boot 3) / spring.factories (Boot 2). 2. Mỗi entry là @Configuration có @Conditional guard: 3. Condition pass → tạo bean; user tự…
Scope xác định vòng đời + số instance của bean. Scope Instance Dùng khi --------- singleton (default) 1 dùng chung toàn app Stateless service, repository prototype Mỗi lần inject/getBean tạo mới Stateful object (command, builder) request / session 1 / HTTP request / session (Web)…
DevTools là optional dependency tăng tốc dev — auto restart + reload khi đổi file. Thêm dependency spring-boot-devtools (scope optional). Tính năng: - Automatic restart — detect file đổi trên classpath → restart context ~1-2s (nhanh nhờ 2 ClassLoader: libs vs app code, chỉ reload…
Bean lifecycle: instantiate (constructor) → inject dependency (@Autowired) → @PostConstruct → bean ready → @PreDestroy (khi context đóng). @PostConstruct — method init gọi sau khi DI xong (trong constructor dependency chưa được inject nên không init ở đó được): load cache từ DB, validate config,…
@Value @ConfigurationProperties --------- Binding 1 property Nhóm property vào class Type-safe Hạn chế (SpEL) Có — Full type conversion Validation Không Có — @Validated + Bean Validation IDE support Kém Có — autocomplete, navigation @Value: 1 property đơn lẻ, SpEL phức tạp. @ConfigurationProperties: config có…
Profiles cho phép config khác nhau theo môi trường (dev/staging/prod) — deploy 1 JAR cho tất cả. File config: application.yml (base) + application-{dev,prod}.yml (merge/override khi profile active). Activate: SPRINGPROFILESACTIVE=prod java -jar app.jar. Bean theo profile: gắn @Profile("dev") / @Profile("prod") trên class bean → bean chỉ…
Circular dependency: A cần B và B cần A → Spring không biết tạo cái nào trước. Spring Boot 2.6+ throw ngay lúc startup: The dependencies of some of the beans form a cycle: a → b → a. Fix (ưu tiên theo thứ tự):…
Khi có nhiều bean cùng type, Spring không biết inject cái nào → ambiguity error lúc startup. Hai cách phân biệt: - @Primary — đặt trên 1 bean làm default khi có nhiều candidate (vd impl production). - @Qualifier("beanName") — đặt tại điểm inject (constructor…
@Controller @RestController --------- Trả về View name (template) Data trực tiếp (JSON/XML) Dùng cho Web MVC (Thymeleaf, JSP) REST API @RestController = @Controller + @ResponseBody. - @Controller method trả view name — return "home" → ViewResolver tìm template templates/home.html render thành HTML. - @RestController trả…
Annotation Lấy từ Ví dụ --------- @PathVariable URI path segment GET /users/42 @RequestParam Query string GET /users?page=2&size=10 @RequestBody Request body (JSON) POST /users - @PathVariable — resource identifier (ID, slug) trong path, bắt buộc: @GetMapping("/users/{id}") + @PathVariable Long id. - @RequestParam — filter/paging/sort từ query…
JPA Hibernate Spring Data JPA ------------ Là gì Specification (JSR-338) Implementation của JPA Abstraction trên JPA Ai định nghĩa Jakarta EE Red Hat Spring - JPA = chuẩn (interface, annotation, JPQL) — chỉ định nghĩa, không chạy được một mình; nhiều implementation: Hibernate, EclipseLink. -…
Lazy Eager --------- Load khi Lần đầu truy cập field Luôn load cùng entity chính Default @OneToMany, @ManyToMany @ManyToOne, @OneToOne Đổi qua attribute fetch: @ManyToOne(fetch = FetchType.LAZY). Vấn đề Eager: luôn load association dù không cần → query thừa, chậm. Vấn đề Lazy: LazyInitializationException khi…
N+1 problem: load list entity (1 query), rồi mỗi entity gọi thêm 1 query lấy association → 1 + N query thay vì 1. Phát hiện: spring.jpa.show-sql=true → thấy query lặp. Fix: Lưu ý: N nhỏ (<5) và query đơn giản có thể không cần…
Authentication (xác thực): "Bạn là ai?" — verify identity (login mật khẩu, JWT, OAuth). Authorization (phân quyền): "Bạn được phép làm gì?" — check permission (role, scope). Authentication luôn xảy ra trước Authorization. Trong Spring Security: - Authentication: implement UserDetailsService.loadUserByUsername() trả về UserDetails (username, password…
Security Filter Chain là chuỗi servlet filter Spring Security đặt trước controller — mỗi filter xử lý 1 concern. Thứ tự filter: Config (Spring Security 6): Custom filter: extend OncePerRequestFilter, override doFilterInternal (vd gắn request-id vào MDC cho logging), đăng ký như @Component hoặc addFilterBefore(...).
JWT (JSON Web Token) = stateless authentication — server không lưu session, verify bằng chữ ký. Flow: Config: bật Resource Server JWT qua oauth2ResourceServer(o - o.jwt(...)) với jwkSetUri (verify bằng public key), session để STATELESS — code đầy đủ xem câu Security Filter Chain. Lưu…
CSRF (Cross-Site Request Forgery): attacker lừa browser của user gửi request đến server — browser tự đính kèm cookie session nên server tưởng là request hợp lệ. Cơ chế chống: server phát CSRF token (random, per-session) nhúng vào form → mọi request thay đổi state…
@SpringBootTest khởi động full ApplicationContext — load toàn bộ bean, auto-config, DB... như production; thường kèm @AutoConfigureMockMvc để gọi endpoint qua MockMvc không cần server thật. Unit test @SpringBootTest --------- Context Không có Spring Full ApplicationContext Tốc độ Nhanh (~ms) Chậm (~5-30s startup) DB Mock/in-memory…
Slice test chỉ load một phần ApplicationContext — nhanh hơn @SpringBootTest, isolate layer cần test. @WebMvcTest — controller layer: @DataJpaTest — repository layer: Slice khác: @JsonTest, @WebFluxTest, @RestClientTest, @DataMongoTest. Chọn: controller → @WebMvcTest; query → @DataJpaTest (+ Testcontainers); full flow → @SpringBootTest. (Boot 3.4+: @MockBean…
@Mock (Mockito) @MockBean (Spring Boot) --------- Spring context Không cần Cần (thay bean trong context) Dùng với Unit test thuần Slice test / @SpringBootTest Tốc độ Nhanh Chậm hơn (invalidate context cache) @Mock — Mockito thuần: chạy với @ExtendWith(MockitoExtension.class), kết hợp @InjectMocks để đưa mock…
HealthIndicator thêm custom health check vào /actuator/health — quan trọng cho Kubernetes liveness/readiness probe. Kết quả: /actuator/health → {"status":"DOWN","components":{"externalApi":{"status":"DOWN"}}}. Liveness vs Readiness (K8s): /actuator/health/readiness = DOWN → K8s dừng route traffic đến pod.
@Async chạy method trong thread pool riêng — non-blocking từ phía caller. Thread pool config (quan trọng): Không có custom executor: Spring dùng SimpleAsyncTaskExecutor (tạo thread mới mỗi task, không pool → OOM khi tải cao). Lưu ý — giống @Transactional: this.method() bypass proxy →…
Spring Cache cache kết quả method — swap backend (in-memory, Redis, Caffeine) không đổi code. Backend Redis: spring.cache.type: redis. TTL đặt qua RedisCacheManagerBuilderCustomizer (entryTtl(Duration.ofMinutes(10))). Lưu ý: @Cacheable trên @Transactional method — nếu transaction rollback, cache vẫn giữ kết quả cũ (stale). Dùng @TransactionalEventListener(phase = AFTERCOMMIT)…
@RestControllerAdvice + @ExceptionHandler xử lý exception tập trung — không try/catch rải khắp controller. Tương tự bắt MethodArgumentNotValidException (lỗi @Valid) trả 400 kèm map field→message từ ex.getBindingResult().getFieldErrors(), và Exception.class trả 500 generic (log full stack, không lộ chi tiết ra ngoài). ProblemDetail (Spring 6, RFC…
Cả 2 trigger Bean Validation trên method argument hoặc field. @Valid (Jakarta) @Validated (Spring) --------- Validation groups Không Có Method-level validation Không Có — (đặt class level) Cơ bản (dùng cái nào cũng được): create(@RequestBody @Valid CreateUserRequest req). Khác biệt thực sự — validation groups:…
Spring Boot load property từ nhiều nguồn — nguồn ưu tiên cao override nguồn thấp (cao → thấp): 1. Command-line args (--server.port=9090) 2. SPRINGAPPLICATIONJSON (env var chứa JSON) 3. Java system properties (-Dserver.port=9090) 4. OS env vars (SERVERPORT=9090) 5. application-{profile}.yml ngoài JAR 6. application.yml ngoài…
@ConditionalOnProperty tạo bean chỉ khi property có giá trị nhất định — feature flag, optional component. Set app.feature.email: true trong config → bean tồn tại; đổi false → biến mất, không sửa code. matchIfMissing = true → bean vẫn tạo khi property không được set.…
Các interface trong Spring Data hierarchy: Lưu ý Spring Data 3.x: PagingAndSortingRepository không còn extends CrudRepository (khác 2.x) — muốn cả CRUD lẫn paging phải extend cả hai, hoặc đơn giản dùng JpaRepository (gộp tất cả + method JPA-specific). Thực tế: hầu hết extend JpaRepository.…
Flyway quản lý schema migration dạng versioned SQL file — audit trail, schema reproducible mọi môi trường. Thêm dependency flyway-core là Spring Boot tự tích hợp (từ Flyway 10 / Boot 3.2+, Postgres/MySQL cần thêm module riêng, vd flyway-database-postgresql). Quy ước: script đặt ở src/main/resources/db/migration/,…
HikariCP là JDBC connection pool — giữ sẵn pool kết nối DB tái sử dụng thay vì mở/đóng connection mỗi request (mở connection tốn hàng chục ms + handshake). Là default của Spring Boot 2+ vì: nhanh nhất trong benchmark (vs Tomcat CP, DBCP2, C3P0)…
ResponseEntity<T cho phép kiểm soát hoàn toàn HTTP response: status code, header, body. Trả object trực tiếp → Spring mặc định 200 OK. Dùng ResponseEntity khi cần status khác 200, custom header, hoặc body có thể null.
@Scheduled chạy method theo lịch định kỳ — cron job, background task. Bật bằng @EnableScheduling trên class config. Cron Spring có 6 field (khác Unix 5 field): {giây} {phút} {giờ} {ngày} {tháng} {thứ}. Lưu ý: mặc định mọi @Scheduled chạy trên 1 thread duy nhất…
Ba cách gọi HTTP từ Spring app đến external API: RestTemplate WebClient RestClient ------------ Model Blocking Non-blocking (reactive) Blocking (fluent) Status Hạn chế — Maintenance mode Có — Active Có — Active (Spring 6.1+) API style Template method Fluent builder Fluent builder RestClient (recommended cho…
Spring Kafka — KafkaTemplate để produce, @KafkaListener để consume. Thêm dependency spring-kafka, config qua spring.kafka. (bootstrap-servers, consumer group-id, JSON serializer/deserializer). Key của message (order.getId()) quyết định partition → message cùng order luôn cùng partition, giữ thứ tự. Error handling: @RetryableTopic — retry tự động với…
Service discovery cho service tìm nhau theo tên logic thay vì IP:port cứng (instance scale lên xuống, IP đổi liên tục). Lựa chọn 2026: 1. Kubernetes Service (phổ biến nhất) — K8s tự discovery qua DNS: gọi http://order-service/api/orders là xong, kube-proxy tự phân tải qua…
Endpoint Actuator nhạy cảm (/env, /heapdump, /loggers) phải được bảo vệ — không để public. 3 lớp (kết hợp được): 1. Chỉ expose cái cần + port riêng: K8s probe/Prometheus vẫn gọi được trong cluster; internet không vào được port 8081. 2. Spring Security: permitAll()…
@ResponseStatus gán HTTP status cho exception class hoặc controller method — khai báo tĩnh thay vì ResponseEntity. Trên exception class: Spring bắt exception → tự trả status đã khai. Trên controller method: vs ResponseEntity: @ResponseStatus cho status cố định, đơn giản; ResponseEntity khi status động,…
Spring Boot 3 (2022) — bản major, breaking changes. Yêu cầu tối thiểu: Java 17 (Boot 2: Java 8), Jakarta EE 10. Thay đổi lớn nhất — namespace: toàn bộ import javax. → jakarta. (vd javax.persistence.Entity → jakarta.persistence.Entity, tương tự validation/servlet; giữ nguyên javax.sql, javax.xml…
Tất cả đều là dạng chuyên biệt của @Component → đều được component scan và tạo bean. Khác nhau ở tầng mà annotation đánh dấu + tính năng thêm: Annotation Tầng Tính năng thêm --------- @Component Generic Không @Service Business logic Không @Repository Data access…
Starters là dependency "gói sẵn" — thêm 1 starter kéo theo tất cả lib + auto-config tương ứng, không cần tự quản từng dependency/version. Starter Gộp gì ------ spring-boot-starter-web Spring MVC + Tomcat + Jackson spring-boot-starter-data-jpa Spring Data JPA + Hibernate + HikariCP spring-boot-starter-security Spring…
Constructor Setter Field ------------ Immutability Có — final Không Không — Mandatory dep Có — Rõ ràng Không — Optional mặc định Không Testability Có — Tốt nhất Có — Tốt Hạn chế — Cần reflection Circular dep Phát hiện sớm Có thể bị ẩn…
Self-invocation: method gọi method khác trong cùng class → @Transactional bị bỏ qua. Spring transaction chạy qua AOP proxy — proxy bọc bean, chặn call từ ngoài để begin/commit. Gọi this.B() đi thẳng vào object, không qua proxy → annotation trên B vô hiệu. Fix:…
CORS — browser chặn request từ origin khác. Spring Boot có nhiều cách config. Global config (recommended): Cách khác: @CrossOrigin(origins = "...") trên controller (đơn giản, per-controller). Lưu ý: khi dùng Spring Security, CORS phải cấu hình qua http.cors(...) trong SecurityFilterChain — config WebMvc bị…
Testcontainers spin up Docker container thật (Postgres, Redis, Kafka...) trong test — integration test với infra thật, không phải H2. Thêm dependency spring-boot-testcontainers + org.testcontainers:postgresql (scope test). Spring Boot 3.1+ — @ServiceConnection: Lợi ích: test với Postgres thật → bắt lỗi SQL mà H2 bỏ…
Spring Boot nhúng web server (Tomcat/Jetty/Undertow) vào JAR — deploy như executable, không cần cài server riêng. Mặc định: Tomcat (spring-boot-starter-web). Đổi sang Jetty: exclude Tomcat khỏi starter-web rồi thêm spring-boot-starter-jetty: Tomcat Jetty Undertow ------------ Default Có Không Không — Memory Trung bình Thấp Thấp…
Spring Data cung cấp Pageable/PageRequest cho pagination và Sort cho sorting. Page response gồm: content, totalElements, totalPages, size, number (trang hiện tại), first, last. Lưu ý: Page thêm 1 count query — với large table hoặc infinite scroll không cần tổng số, dùng Slice<T.
Actuator + Micrometer export metric sang Prometheus → Grafana visualize. Thêm spring-boot-starter-actuator + micrometer-registry-prometheus, rồi expose: Custom metric: Prometheus: thêm job metricspath: /actuator/prometheus, target app:8080. Built-in metric: JVM memory/GC, Tomcat threads, HikariCP pool, HTTP count/latency, cache hit. Grafana: import dashboard "Spring Boot Statistics" để có…
SpringDoc OpenAPI tự generate OpenAPI 3 spec từ controller/DTO — không viết YAML thủ công. Thêm springdoc-openapi-starter-webmvc-ui. Out of the box: GET /v3/api-docs (JSON spec), GET /swagger-ui.html (UI tương tác). Customize: Tắt trên production: springdoc.swagger-ui.enabled: false, springdoc.api-docs.enabled: false. Vs Springfox: Springfox (Swagger 2) ngừng maintain…
BeanFactory và ApplicationContext đều là Spring IoC container — ApplicationContext là superset. Feature BeanFactory ApplicationContext --------- Lazy loading Có — Default Không — Eager (singleton tạo lúc startup) AOP, @Transactional Không Có Event publishing Không Có — (ApplicationEvent) MessageSource (i18n) Không Có Web context Không…
AOP (Aspect-Oriented Programming) tách cross-cutting concern (logging, security, transaction, metrics) khỏi business logic. Khái niệm: Aspect (module chứa logic), Pointcut (chọn method bị intercept), Advice (@Before/@After/@Around/@AfterThrowing), JoinPoint (điểm thực thi cụ thể). Pointcut expression phổ biến: execution( com.example.service..(..)) (mọi method trong package), @annotation(Transactional) (method có…
Cả hai lắng nghe ApplicationEvent, khác ở thời điểm chạy so với transaction. - @EventListener — chạy ngay khi publish, trong cùng transaction. Listener throw → transaction rollback toàn bộ. - @TransactionalEventListener — chạy sau khi transaction commit thành công. Transaction rollback → event bị…
Method-level security bảo vệ từng method bằng annotation thay vì chỉ ở URL level. Bật bằng @EnableMethodSecurity (thay @EnableGlobalMethodSecurity đã deprecated). @PreAuthorize — kiểm tra trước khi method chạy (dùng SpEL): @PostAuthorize — kiểm tra sau khi method chạy (check return value): @PostAuthorize("returnObject.owner == authentication.name").…
Virtual Threads (Project Loom, Java 21) là thread cực nhẹ do JVM quản lý — không phải OS thread. Bật trong Spring Boot 3.2+ bằng 1 dòng config: spring.threads.virtual.enabled: true — Spring Boot tự dùng cho Tomcat, @Async, @Scheduled. Vì sao đáng giá: OS thread…
Spring Boot không thay thế Spring Framework — nó là lớp tiện ích xây trên Spring để bỏ cấu hình thủ công. Spring Framework Spring Boot --------- Vai trò Nền tảng cốt lõi (IoC, DI, AOP, MVC) Lớp tiện ích trên Spring Cấu hình Thủ…
Cả hai chặn request trước controller, nhưng ở tầng khác nhau. Filter (Servlet) HandlerInterceptor (Spring MVC) --------- Tầng Servlet container (trước DispatcherServlet) Bên trong DispatcherServlet Biết controller xử lý? Không — Chưa Có — Có (handler argument) Truy cập Spring context Hạn chế Có —…
JPA map class Java ↔ bảng DB qua annotation — không viết SQL DDL thủ công. - @Entity — class là JPA entity (1 bảng); @Table — tên bảng. - @Id — khoá chính; @GeneratedValue — cách sinh ID (IDENTITY auto-increment phổ biến, SEQUENCE, UUID).…
4 trạng thái của entity đối với Persistence Context: - Transient (new) — vừa new, JPA chưa biết đến, chưa có row trong DB. - Managed (persistent) — đang được Persistence Context theo dõi (sau persist(), find(), hoặc query trả về) → hưởng dirty checking:…
@GetMapping, @PostMapping, @PutMapping, @DeleteMapping, @PatchMapping là shortcut (composed annotation) của @RequestMapping(method = ...), có từ Spring 4.3: - @GetMapping("/users") = @RequestMapping(value = "/users", method = RequestMethod.GET). Khác biệt đáng nhớ: - @RequestMapping đặt được ở class level làm base path chung cho cả controller; các…
Entity = object map với bảng DB, do JPA quản lý. DTO (Data Transfer Object) = object thuần chở data qua boundary (API response/request), không dính persistence. Vì sao không trả entity thẳng ra controller: 1. Lộ cấu trúc DB — đổi schema là vỡ…
Config Server tập trung config cho nhiều service — thay vì mỗi service tự giữ application.yml, tất cả đọc từ 1 nguồn chung, thường là Git repo (config được version, review, audit qua commit). Server: dependency spring-cloud-config-server + @EnableConfigServer, trỏ spring.cloud.config.server.git.uri đến repo chứa file…
API Gateway = cửa vào duy nhất của hệ microservices — client chỉ gọi 1 endpoint, gateway route đến đúng service phía sau. Lợi ích chính: gom các concern chung về 1 chỗ — authentication, rate limiting, CORS, logging, retry — thay vì lặp lại…
Spring Boot tự bật auto-config dựa trên classpath. Tắt một cái cụ thể có 3 cách: 1. Thuộc tính exclude của @SpringBootApplication (thực chất uỷ quyền cho @EnableAutoConfiguration): 2. @EnableAutoConfiguration(exclude = ...) nếu không dùng annotation gộp. 3. Qua property — dùng khi class không…
@ComponentScan bảo Spring quét package tìm class gắn stereotype (@Component, @Service, @Repository, @Controller, @Configuration) để đăng ký thành bean. Base package mặc định: package chứa chính class khai báo annotation. Vì @SpringBootApplication đã gộp sẵn @ComponentScan, Spring quét từ package của lớp main trở xuống…
Không. Mặc định Spring chỉ đánh dấu rollback khi method ném RuntimeException (unchecked) hoặc Error. Checked exception ném ra từ method transactional vẫn commit như thường. Muốn rollback với checked exception thì khai báo tường minh: Ngược lại, noRollbackFor giữ commit cho một loại unchecked…
Dùng ApplicationRunner hoặc CommandLineRunner. Cả hai có duy nhất một method run(...), được gọi ngay trước khi SpringApplication.run(...) trả về — tức là toàn bộ context đã sẵn sàng, web server đã lên. Khác nhau: - CommandLineRunner nhận tham số dạng String... thô; ApplicationRunner nhận…
Class gắn @ConfigurationProperties("prefix") phải trở thành bean thì Spring mới bind. Có ba cách: - @EnableConfigurationProperties(MyProperties.class) trên một class @Configuration. - @ConfigurationPropertiesScan trên class main (quét cả package). - Gắn thêm @Component lên chính class đó. Relaxed binding: tên property trong Environment không cần trùng…
Graceful shutdown là chế độ khi nhận tín hiệu dừng (SIGTERM), web server ngừng nhận request mới nhưng vẫn cho các request đang xử lý chạy hết trong một khoảng ân hạn rồi mới tắt. Không có nó, container bị kill giữa chừng sẽ trả…
Không. Dependency được resolve một lần lúc singleton khởi tạo: Spring tạo đúng một instance prototype, tiêm vào, và singleton dùng lại instance đó suốt vòng đời. Đây là bẫy hay được hỏi vì code nhìn qua tưởng đúng. Muốn lấy instance mới mỗi lần…
Khác ở chỗ inter-bean call có được container quản lý hay không. - @Configuration (full mode): Spring tạo CGLIB subclass cho class config. Một @Bean method gọi trực tiếp @Bean method khác sẽ bị chặn và trả về singleton trong container. - @Bean trong class…
Quy tắc gốc của Spring AOP: - Target implement ít nhất một interface → dùng JDK dynamic proxy, proxy chỉ expose các interface đó. - Target không implement interface nào → dùng CGLIB, tạo runtime một subclass của chính class đó. Ép dùng CGLIB bằng…
Vì chúng đi qua hai cơ chế khác nhau. 1. @Valid trên @RequestBody — validate do argument resolver của Spring MVC thực hiện sau khi deserialize JSON. Lỗi ném MethodArgumentNotValidException (kế thừa BindException), có BindingResult chứa từng FieldError. 2. Constraint đặt thẳng trên tham số…
Bằng ProblemDetail — cài đặt của RFC 9457 (bản kế thừa RFC 7807), trả Content-Type: application/problem+json với các field chuẩn type, title, status, detail, instance cộng field mở rộng tuỳ ý. Hai cách dùng: Kế thừa ResponseEntityExceptionHandler trong @ControllerAdvice để nhận sẵn handler cho toàn…
Từ Spring Boot 2.6, circular reference giữa các bean bị cấm mặc định. Trước đó container tự gỡ vòng phụ thuộc bằng cách tiêm bean chưa khởi tạo xong, giờ nó fail-fast ngay lúc startup. Cách chữa nhanh (chỉ để unblock deploy): Cách chữa đúng,…
- spring.profiles.active: danh sách profile đang bật. Đặt lại giá trị này ở nơi có độ ưu tiên cao hơn sẽ thay thế danh sách cũ, không cộng dồn. Thường truyền lúc chạy: --spring.profiles.active=prod. - spring.profiles.include: cộng thêm profile vào danh sách đang bật, dùng…
Spring Data JPA có ba cách khai báo truy vấn, chọn theo độ phức tạp: 1. Derived query — Spring sinh JPQL từ tên method. Ngắn gọn, an toàn kiểu, nhưng tên dài ra rất nhanh khi nhiều điều kiện. 2. @Query với JPQL —…
Lỗi này ném ra khi bạn chạm vào một association LAZY sau khi persistence context đã đóng — proxy không còn EntityManager nào để nạp dữ liệu. Vì sao dev không thấy: Spring Boot mặc định bật spring.jpa.open-in-view=true (Open Session In View). Interceptor giữ EntityManager…
Password không bao giờ lưu dạng plaintext, và cũng không dùng hash nhanh (MD5, SHA-256) vì tấn công brute-force bằng GPU quá rẻ. Spring Security dùng hàm băm chậm có salt, mặc định là BCrypt. Hàm này trả về DelegatingPasswordEncoder — nó lưu chuỗi hash…
Từ Spring Security 6 (Spring Boot 3), WebSecurityConfigurerAdapter không còn tồn tại. Thay vì kế thừa một adapter và override method, bạn khai báo một bean SecurityFilterChain: Ba thay đổi cần nhớ khi migrate: - antMatchers / mvcMatchers → requestMatchers. - Lambda DSL thay cho…
Vì entity lấy ra từ repository đang ở trạng thái managed trong persistence context, và Hibernate có cơ chế dirty checking tự động. Cơ chế: khi load entity, Hibernate giữ lại một snapshot giá trị các thuộc tính. Tại thời điểm flush (trước khi commit,…
Cả hai đều nói với Hibernate "nạp luôn association này trong cùng một câu SQL", nhưng khai báo ở tầng khác nhau. join fetch nằm trong JPQL — gắn chặt với truy vấn đó: @EntityGraph là fetch plan khai báo tách rời, dán lên method…
Yêu cầu cốt lõi: một entity phải bằng chính nó qua mọi trạng thái transient → managed → detached, và hashCode phải không đổi trong suốt vòng đời object. Vì sao dùng thẳng ID auto-increment là sai: lúc new entity, id còn null nên hashCode…
Luồng chuẩn đi qua bốn mắt xích, mỗi mắt xích một nhiệm vụ: 1. Authentication filter (vd UsernamePasswordAuthenticationFilter) bóc username/password khỏi request, gói thành UsernamePasswordAuthenticationToken chưa xác thực rồi đưa cho AuthenticationManager. 2. AuthenticationManager (mặc định là ProviderManager) duyệt danh sách AuthenticationProvider để tìm cái…
Đây là bài toán lost update, xử lý bằng optimistic locking với @Version — phù hợp vì đọc nhiều hơn ghi và người dùng giữ dữ liệu trên form khá lâu (entity ở trạng thái detached), không thể giữ lock DB suốt thời gian đó.…
Khác nhau ở thời điểm kích hoạt, không phải ở kết quả xoá. - CascadeType.REMOVE: chỉ chạy khi xoá entity cha. Xoá Order thì các OrderItem bị xoá theo. - orphanRemoval = true: chạy khi child bị tách khỏi cha, dù cha vẫn tồn tại.…
Nguyên nhân là thứ tự filter: preflight OPTIONS của trình duyệt không mang credential (không cookie, không header Authorization). Nếu filter chain của Spring Security chạy trước phần xử lý CORS, nó thấy request không xác thực và trả 401 ngay — chưa bao giờ…