Bean_Proxying
Trong Spring, Bean Proxying là một cơ chế sử dụng Proxy (có thể là JDK Dynamic Proxy hoặc CGLIB) để thay thế Bean gốc bằng một Bean được wrap lại, nhằm thêm các tính năng bổ sung như AOP, Transaction Management, Security, Lazy Initialization, v.v.
1. Vì sao Spring sử dụng Bean Proxying?
Spring sử dụng Bean Proxying để:
Hỗ trợ AOP (Aspect-Oriented Programming): Giúp chèn logic trước, sau hoặc xung quanh method mà không cần sửa code gốc.
Hỗ trợ @Transactional: Giúp Spring quản lý giao dịch tự động.
Tạo Singleton Proxy: Cho phép Bean singleton có thể chứa dependencies có scope khác nhau (ví dụ: Prototype).
Hỗ trợ Lazy Initialization: Trì hoãn khởi tạo Bean đến khi nó được sử dụng lần đầu tiên.
2. Các Loại Proxy trong Spring
Spring có hai cách để tạo Proxy:
JDK Dynamic Proxy (Interface-based Proxying)
CGLIB Proxy (Class-based Proxying)
2.1. JDK Dynamic Proxy
Chỉ hoạt động khi Bean implement interface.
Sử dụng
java.lang.reflect.Proxy
.Tạo Proxy chỉ cho các method trong interface, không áp dụng cho method của class cụ thể.
Ví dụ:
Khi Spring thấy
@Transactional
, nó tạo một Proxy choMyServiceImpl
bằng JDK Dynamic Proxy.Khi bạn gọi
doSomething()
, thực chất là gọi thông qua Proxy, chứ không phải trực tiếp vàoMyServiceImpl
.
2.2. CGLIB Proxy
Được sử dụng khi Bean không implement interface hoặc bạn cấu hình Spring để dùng CGLIB.
Sử dụng subclassing thay vì interface.
Dựa trên thư viện CGLIB (Code Generation Library) để tạo subclass của Bean và override method.
Hoạt động với cả interface method và non-interface method.
Ví dụ:
Vì MyService
không implement interface nào, Spring sẽ dùng CGLIB Proxy để tạo subclass của MyService
và override doSomething()
.
💡 Lưu ý: CGLIB Proxy không hoạt động với các final methods vì không thể override chúng.
Cấu Hình Spring Để Dùng Proxy
Mặc định, Spring chọn Proxy phù hợp dựa vào cấu trúc Bean. Tuy nhiên, bạn có thể ép buộc Spring sử dụng kiểu Proxy mong muốn.
Proxying trong Một Số Tính Năng Quan Trọng của Spring
AOP (Aspect-Oriented Programming)
Spring AOP sử dụng Proxy để chèn logic vào trước/sau method.
Transaction Management (@Transactional)
Spring sử dụng Proxy để quấn các method có @Transactional
, giúp tự động bắt đầu và commit transaction.
Lazy Initialization
Spring dùng Proxy để trì hoãn khởi tạo Bean cho đến khi nó thực sự được sử dụng.
Hạn Chế của Proxy trong Spring
Không thể proxy method
final
→ Vì Proxy cần override method để can thiệp logic.Không proxy được
private
method → Proxy chỉ hoạt động vớipublic
vàprotected
method.JDK Proxy chỉ hoạt động với Interface → Nếu không có Interface, phải dùng CGLIB.
Self-invocation không hoạt động với Proxy → Khi một method trong cùng một class gọi method khác trong chính nó, Spring không thể áp dụng Proxy.
Last updated