Learning Outcome & Exercises: Spring Core & Boot
Tổng kết chương Spring Core & Boot: học xong mình phải làm được gì, và làm bài tập nào để chứng minh?
Đọc hiểu chưa đủ để đi phỏng vấn. Mỗi chương kết thúc bằng những việc làm được và chứng minh được: có code chạy, có test cho cả trường hợp lỗi, có log hoặc số đo. Bài tập nằm trong repo riêng java-backend-interview-labs, thư mục labs/spring-core.
1. Mục tiêu đầu ra
Học xong chương này, bạn tự làm được:
- Chứng minh bằng integration test rằng self-invocation bỏ qua proxy của @Transactional và @Async.
- Giải thích lifecycle bean và khác biệt singleton / prototype / request scope bằng log.
- Đọc được báo cáo auto-configuration (--debug / conditions endpoint) để biết vì sao một bean được tạo.
2. Basic: Bean scope & lifecycle
Trạng thái: ⬜ Chưa triển khai: chưa có code/test, chưa tính là hoàn thành
Inject prototype bean vào singleton, quan sát nó không đổi; sửa bằng ObjectProvider và log @PostConstruct/@PreDestroy.
Bài liên quan: Bean scope & lifecycle, IoC & Dependency Injection
Hoàn thành khi:
- Test so sánh identity hai lần lấy bean
- Log lifecycle trong evidence/
3. Intermediate: Self-invocation phá @Transactional
Trạng thái: ⬜ Chưa triển khai: chưa có code/test, chưa tính là hoàn thành
Method A gọi this.b() có @Transactional(REQUIRES_NEW) và @Async; test chứng minh không có transaction mới và chạy cùng thread; sửa bằng tách bean.
Bài liên quan: AOP & proxy, Events, scheduling, @Async
Hoàn thành khi:
- Test failure case và test bản sửa
- Giải thích proxy boundary bằng sơ đồ
4. Challenge: Tự viết starter
Trạng thái: ⬜ Chưa triển khai: chưa có code/test, chưa tính là hoàn thành
Viết starter nhỏ có @ConditionalOnProperty và @ConfigurationProperties; test bằng ApplicationContextRunner cả khi bật lẫn tắt.
Bài liên quan: Auto-configuration & starters, Profile & cấu hình, Tự viết annotation
Hoàn thành khi:
- 2 test conditional pass
- Không hardcode giá trị nhạy cảm
5. Tiêu chí hoàn thành chung
- Tự giải thích được bài toán và vì sao chọn giải pháp.
- Code chạy được bằng lệnh ghi trong README, không chứa secret.
- Có test tự động cho happy path và failure path.
- Có log hoặc số đo trong
evidence/chứng minh kết quả. - Có câu trả lời phỏng vấn ngắn bằng tiếng Việt và tiếng Anh.
- README của lab có link ngược về bài học tương ứng.
6. Lab và trạng thái
| Mức | Bài tập | Trạng thái | Test / bằng chứng |
|---|---|---|---|
| Basic | Bean scope & lifecycle | ⬜ Chưa triển khai: chưa có code/test, chưa tính là hoàn thành | — |
| Intermediate | Self-invocation phá @Transactional | ⬜ Chưa triển khai: chưa có code/test, chưa tính là hoàn thành | — |
| Challenge | Tự viết starter | ⬜ Chưa triển khai: chưa có code/test, chưa tính là hoàn thành | — |
Repo lab: java-backend-interview-labs/labs/spring-core. TODO: link GitHub là placeholder cho tới khi repo được push.
evidence/; chỉ đánh dấu xong khi có bằng chứng.Phỏng vấn hỏi về Spring Core & Boot, câu nào hay gặp nhất và trả lời sao?
Q1. Vì sao gọi method @Transactional trong cùng class thì không có transaction?
🇻🇳 Tiếng Việt:
Spring áp transaction qua proxy. Gọi this.method() là gọi thẳng object thật, không đi qua proxy nên interceptor không chạy. Cách sửa là tách sang bean khác hoặc gọi qua proxy.
🇬🇧 English:
Spring applies transactions through a proxy. Calling this.method() invokes the target object directly, bypassing the proxy, so the interceptor never runs. The fix is to move the method to another bean or call it through the proxy.
Cách nhớ ngắn gọn
- Mỗi bài tập = code + test + log.
- Luôn có ít nhất một failure case.
- Chưa có bằng chứng thì chưa xong.
Tự kiểm tra
Bài tập Basic (Bean scope & lifecycle) được coi là xong khi nào?
Test so sánh identity hai lần lấy bean; Log lifecycle trong evidence/. Chưa có code chạy và bằng chứng thì chưa tính là xong.
Bài tập Intermediate (Self-invocation phá @Transactional) được coi là xong khi nào?
Test failure case và test bản sửa; Giải thích proxy boundary bằng sơ đồ. Chưa có code chạy và bằng chứng thì chưa tính là xong.
Bài tập Challenge (Tự viết starter) được coi là xong khi nào?
2 test conditional pass; Không hardcode giá trị nhạy cảm. Chưa có code chạy và bằng chứng thì chưa tính là xong.