Lời mở
Có một câu mà người mới đi làm hay hỏi:
“Ơ, sao nó chạy được?”
Người đi làm lâu rồi thì thôi không hỏi nữa. Không phải vì đã biết câu trả lời, mà vì đã quen với việc không biết.
Bạn thêm một dòng annotation lên đầu một method. Bạn không viết thêm một dòng logic nào. Method đó vẫn y nguyên như cũ. Vậy mà bây giờ nó mở giao dịch, nó ghi cache, nó chạy ở luồng khác. Cái gì đã làm việc đó?
Câu trả lời quen thuộc là “Spring làm”. Câu đó đúng, và nó vô dụng - nó chỉ đổi một sự bí ẩn thành một cái tên riêng. Ngày mọi thứ chạy ngon thì cái tên riêng ấy đủ dùng. Ngày một cái annotation im lặng không có tác dụng, một cái giao dịch không được mở, một giá trị lẽ ra phải có thì lại là null - thì cái tên riêng ấy không giúp bạn được gì cả, vì bạn không biết phải đi tìm ở đâu.
Quyển này nói về một giả định mà gần như mọi lập trình viên đều mang theo mà chưa bao giờ nói thành lời:
Cái tôi nhìn thấy trong code, chính là cái đang chạy.
Không phải.
Giữa dòng code bạn viết và thứ thật sự chạy lúc đó, gần như lúc nào cũng có một cái gì đó đứng chen vào. Nó được sinh ra lúc ứng dụng khởi động, ở một pha mà bạn không đứng đó nhìn. Nó mang đúng hình dạng của thứ bạn định gọi, nên bạn tưởng mình đang gọi thẳng. Và phần lớn thời gian nó làm việc rất tốt - tốt tới mức bạn quên mất nó tồn tại.
Cho tới hôm bạn gặp một con bug mà nó không giải thích được bằng code bạn nhìn thấy.
Hai mươi bài trong quyển này, mỗi bài là một con bug như thế. Không bài nào là bug hiếm; tất cả đều là những thứ xảy ra ở mọi dự án Spring trên đời, mỗi tuần. Cái mình muốn bạn nhận ra không phải hai mươi cách sửa, mà là chuyện này: cả hai mươi con bug ấy đều mọc từ đúng một chỗ. Chúng chỉ khác nhau ở việc cái tầng trung gian ấy đang đội lốt gì.
Mình sẽ không kể cho bạn nghe cái chỗ đó là gì ngay bây giờ. Nếu kể, bạn sẽ ghi nhớ nó như một thông tin, rồi quên sau ba tuần. Bạn phải tự gặp nó vài lần, ở vài hình dạng khác nhau, tự thấy nó lặp lại - rồi tự đặt tên cho nó. Cái tên bạn tự đặt sẽ ở lại lâu hơn cái tên mình đưa.
Mạch đọc đi từ vòng đời tạo bean tới danh sách resolver, proxy, transaction, persistence context, mapping và cấu hình. Đọc theo thứ tự để câu hỏi kia trở thành phản xạ. Khi một hành vi không thể giải thích bằng dòng code trước mắt, đừng đọc lại nó lần thứ mười. Hãy tìm thứ đang chen vào giữa.
Bắt đầu bằng một chuyện nhỏ nhất có thể: một biến @Value bị null, và Spring không hề báo lỗi.
Đừng chỉ hỏi hệ thống đang làm gì. Hãy hỏi giả định nào đang khiến bạn tin nó sẽ làm như vậy.