- Spring Boot là gì và có những ưu điểm gì?
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.…
- Dependency Injection (DI) là gì? Spring cài đặt DI thế nào?
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 là gì và hoạt động thế nào?
@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…
- @Bean và @Component khác nhau thế nào?
@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:…
- application.properties và application.yml là gì? Externalized config hoạt động thế nào?
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…
- Spring Boot Actuator dùng để làm gì?
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 và @Repository là gì?
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…
- Spring transaction management và @Transactional là gì?
@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…
- @Transactional(readOnly=true) có tác dụng gì?
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,…
- OAuth 2.1 + Spring Authorization Server hoạt động như thế nào trong kiến trúc microservices?
- Sự khác biệt giữa Authorization Server và Resource Server trong Spring Security 6?
- Spring MVC và Spring WebFlux khác nhau thế nào? Khi nào chọn cái nào?
- Mono, Flux và backpressure trong Spring WebFlux là gì?
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…
- Đánh đổi giữa Testcontainers và H2 in-memory database trong CI/CD là gì?
- @SpringBootApplication là gì? Gồm những annotation nào?
@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 trong Spring Boot hoạt động thế nào?
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ự…
- Bean scope trong Spring là gì? Singleton và Prototype khác nhau thế nào?
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)…
- Spring Boot DevTools có tác dụng gì?
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 trong Spring Boot: @PostConstruct và @PreDestroy dùng khi nào?
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 và @ConfigurationProperties khác nhau thế nào? Khi nào dùng cái nào?
@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ó…
- Spring Profiles là gì và cách dùng như thế nào?
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 trong Spring là gì? Cách phát hiện và fix?
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ự):…
- @Primary và @Qualifier trong Spring dùng khi nào?
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…
- @RestController và @Controller khác nhau thế nào?
@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ả…
- @PathVariable, @RequestParam và @RequestBody khác nhau thế nào?
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…
- DispatcherServlet trong Spring MVC hoạt động như thế nào?
- JPA và Hibernate khác nhau thế nào? Spring Data JPA là gì?
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 loading và eager loading trong JPA là gì? Khi nào dùng cái nào?
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 query problem trong JPA là gì? Cách fix?
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 và Authorization trong Spring Security khác nhau thế nào?
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…
- Spring Security Filter Chain là gì? Hoạt động như thế nào?
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 authentication trong Spring Security hoạt động thế nào?
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 protection trong Spring Security là gì? Khi nào cần bật/tắt?
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 là gì? Khác gì với unit test thông thường?
@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 tests trong Spring Boot: @WebMvcTest và @DataJpaTest dùng khi nào?
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…
- @MockBean và @Mock khác nhau thế nào?
@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…
- Cách tạo custom HealthIndicator trong Spring Boot Actuator?
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 và @EnableAsync trong Spring Boot hoạt động thế nào?
@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 →…
- @Cacheable và @CacheEvict trong Spring Cache hoạt động thế nào?
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)…
- @ControllerAdvice và @ExceptionHandler dùng để làm gì?
@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…
- @Valid và @Validated trong Spring Boot khác nhau thế nào?
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:…
- Thứ tự ưu tiên property trong Spring Boot như thế nào?
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 dùng để làm gì?
@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.…
- CrudRepository, JpaRepository và PagingAndSortingRepository khác nhau thế nào?
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.…
- Transaction propagation trong Spring: các loại phổ biến là gì?
- Transaction isolation levels trong Spring: READ_COMMITTED và REPEATABLE_READ khác nhau thế nào?
- Database migration với Flyway trong Spring Boot hoạt động thế nào?
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à gì? Tại sao là default connection pool trong Spring Boot?
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 trong Spring MVC dùng để làm gì?
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 và @EnableScheduling dùng để làm gì?
@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…
- RestTemplate, WebClient và RestClient khác nhau thế nào?
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 integration: cách produce và consume message?
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 và load balancing trong microservices với Spring Cloud?
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…
- Cách bảo vệ Actuator endpoint trong production?
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 dùng khi nào?
@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 khác gì so với Spring Boot 2? Những thay đổi lớn khi migrate?
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…
- Saga pattern giải quyết bài toán gì trong microservices?
- @Component, @Service, @Repository và @Controller khác nhau thế nào?
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…
- Spring Boot Starters là gì? Nêu các starter thường dùng.
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 injection, setter injection và field injection khác nhau thế nào? Cái nào nên dùng?
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…
- save(), saveAndFlush() và flush() trong JPA khác nhau thế nào?
- @Transactional self-invocation problem là gì?
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 trong Spring Boot cấu hình như thế nào?
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 trong Spring Boot dùng để làm gì?
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 Embedded Server là gì? Thay đổi sang Jetty như thế nào?
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…
- Cách implement Pagination và Sorting với Spring Data JPA?
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.
- Spring Boot Actuator metric với Prometheus và Grafana tích hợp thế nào?
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ó…
- Circuit Breaker pattern với Resilience4j trong Spring Boot hoạt động thế nào?
- OpenAPI (Swagger) tích hợp với Spring Boot thế nào?
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…
- ApplicationContext và BeanFactory khác nhau thế nào?
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…
- Spring AOP là gì? @Aspect, @Around và pointcut hoạt động thế nào?
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ó…
- @TransactionalEventListener khác @EventListener thế nào? Dùng khi nào?
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ị…
- @PreAuthorize và method-level security trong Spring Security hoạt động thế nào?
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 (Java 21) trong Spring Boot 3.2 hoạt động thế nào? Khác gì WebFlux?
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…
- GraalVM Native Image với Spring Boot 3 hoạt động thế nào? Ưu/nhược điểm?
- Spring Framework và Spring Boot khác nhau thế nào?
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ủ…
- Filter và HandlerInterceptor trong Spring khác nhau thế nào?
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ó —…
- @Entity, @Id, @GeneratedValue và mapping quan hệ trong JPA hoạt động thế nào?
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).…
- Entity lifecycle trong JPA: transient, managed, detached, removed là gì?
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:…
- @RequestMapping và @GetMapping khác nhau thế nào?
@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…
- DTO và Entity khác nhau thế nào? Vì sao không trả entity thẳng ra API?
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ỡ…
- Spring Cloud Config Server dùng để làm gì?
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 là gì? Spring Cloud Gateway hoạt động thế nào?
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…
- Loại trừ/tắt một auto-configuration cụ thể trong Spring Boot thế nào?
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 hoạt động thế nào, đặt base packages ra sao?
@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…
- Method có `@Transactional` ném checked exception thì transaction có rollback khô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…
- Muốn chạy một đoạn code ngay sau khi app khởi động thì dùng gì? `CommandLineRunner` khác `@PostConstruct` thế nào?
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…
- `@ConfigurationProperties` cần gì để bind được? Relaxed binding hoạt động ra sao?
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 trong Spring Boot là gì? Cấu hình thế nào?
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ả…
- Inject một bean scope `prototype` vào bean `singleton` thì mỗi lần dùng có ra instance mới không?
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…
- Đặt `@Bean` trong class `@Component` thay vì `@Configuration` thì khác gì?
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…
- Spring chọn JDK dynamic proxy hay CGLIB proxy dựa trên tiêu chí gì?
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ì sao validate `@RequestBody` và validate `@RequestParam` lại ném hai loại exception khác nhau?
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ố…
- Spring Boot 3 chuẩn hoá response lỗi bằng gì? `ProblemDetail` dùng ra sao?
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…
- Nâng cấp lên Spring Boot 2.6+ thì app không khởi động được vì `BeanCurrentlyInCreationException` — xử lý thế nào?
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,…
- Cấu hình theo môi trường: `spring.profiles.active`, `spring.profiles.include` và `spring.profiles.group` khác nhau thế nào?
- 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…
- Cấu hình liveness và readiness probe cho Kubernetes bằng Actuator như thế nào? Hai probe khác nhau ở đâu?
- Đã `try/catch` nuốt exception rồi mà vẫn nhận `UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only` — vì sao?
- `REQUIRES_NEW` và `NESTED` khác nhau thế nào? Rủi ro khi lạm dụng `REQUIRES_NEW`?
- Đặt `@Transactional` lên method `private` hoặc method `final` thì có chạy không?
- Một bean khai báo cả `@PostConstruct`, `InitializingBean` và `initMethod` thì thứ tự chạy ra sao?
- Derived query method và `@Query` khác nhau thế nào? Khi nào dùng native query?
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 —…
- `LazyInitializationException` xảy ra khi nào? Vì sao trên môi trường dev không thấy nhưng lên production lại gặp?
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 lưu trong DB thế nào? `PasswordEncoder` mặc định của Spring Security là gì và tiền tố `{bcrypt}` để làm gì?
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…
- Spring Security 6 cấu hình bảo mật thế nào khi `WebSecurityConfigurerAdapter` đã bị bỏ?
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ì sao sửa field của entity trong method `@Transactional` mà không gọi `save()` thì DB vẫn được cập nhật?
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,…
- `@EntityGraph` và `join fetch` khác nhau thế nào? Khi nào chọn cái nào để chữa N+1?
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…
- Viết `equals()` và `hashCode()` cho JPA entity thế nào cho đúng? Vì sao không dùng thẳng ID sinh tự động?
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…
- Mô tả luồng đăng nhập username/password trong Spring Security: request đi qua những thành phần nào?
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…
- Hai người cùng mở một đơn hàng và cùng bấm lưu, người sau ghi đè người trước. Em thiết kế luồng chống việc này thế nào?
Đâ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 đó.…
- `CascadeType.REMOVE` và `orphanRemoval = true` khác nhau thế nào? Khi nào bắt buộc dùng `orphanRemoval`?
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.…
- Frontend gọi API bị lỗi CORS, request `OPTIONS` trả về 401 dù đã có `@CrossOrigin`. Nguyên nhân và cách sửa?
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ờ…
- Log hiện cảnh báo `HHH000104: firstResult/maxResults specified with collection fetch; applying in memory`. Chuyện gì đang xảy ra và sửa thế nào?
- Ứng dụng ném `MultipleBagFetchException: cannot simultaneously fetch multiple bags`. Vì sao và xử lý ra sao?
- Import 100.000 bản ghi bằng `saveAll()` rất chậm. Em đã đặt `hibernate.jdbc.batch_size=50` mà log vẫn ra từng câu INSERT một. Vì sao?
- Production báo `HikariPool-1 - Connection is not available, request timed out after 30000ms`. Em chẩn đoán và xử lý thế nào? `maximumPoolSize` nên đặt bao nhiêu?
- Với JWT stateless, em thiết kế luồng refresh token và xử lý logout/thu hồi quyền thế nào?