Trước hết, không có quá trình tạo mã nào diễn ra, có nghĩa là: không có CGLib, không có quá trình tạo mã byte. Cách tiếp cận cơ bản là một phiên bản proxy JDK được tạo theo chương trình bằng cách sử dụng ProxyFactory
API của Spring để quay lại giao diện và MethodInterceptor
chặn tất cả các lệnh gọi đến phiên bản và định tuyến phương thức đến những vị trí thích hợp:
- Nếu kho lưu trữ đã được khởi tạo với một phần triển khai tùy chỉnh (xem phần đó của tài liệu tham khảo để biết chi tiết) và phương thức được gọi được thực hiện trong lớp đó, thì lệnh gọi sẽ được chuyển đến đó.
- Nếu phương thức là một phương thức truy vấn (xem
DefaultRepositoryInformation
cách xác định điều đó), cơ chế thực thi truy vấn cụ thể của cửa hàng sẽ khởi động và thực thi truy vấn được xác định sẽ được thực thi cho phương thức đó khi khởi động. Vì vậy, một cơ chế phân giải được đặt ra để cố gắng xác định các truy vấn được khai báo rõ ràng ở nhiều nơi khác nhau (sử dụng @Query
trên phương thức, các truy vấn có tên JPA) cuối cùng quay trở lại truy vấn dẫn xuất từ tên phương thức. Để phát hiện cơ chế truy vấn, hãy xem JpaQueryLookupStrategy
. Bạn có thể tìm thấy lôgic phân tích cú pháp cho dẫn xuất truy vấn trong PartTree
. Bản dịch cụ thể của cửa hàng thành một truy vấn thực tế có thể được nhìn thấy, ví dụ: trong JpaQueryCreator
.
- Nếu không có cách nào ở trên áp dụng, phương thức được thực thi phải được thực thi bởi một lớp cơ sở kho lưu trữ cụ thể cho cửa hàng (
SimpleJpaRepository
trong trường hợp JPA) và cuộc gọi được chuyển đến một thể hiện của phương thức đó.
Phương thức đánh chặn thực hiện logic định tuyến đó là logic định tuyến QueryExecutorMethodInterceptor
mức cao có thể được tìm thấy tại đây .
Việc tạo ra các proxy đó được gói gọn trong một triển khai mẫu Factory dựa trên Java tiêu chuẩn. Tạo proxy cấp cao có thể được tìm thấy trong RepositoryFactorySupport
. Sau đó, các triển khai dành riêng cho cửa hàng sẽ thêm các thành phần cơ sở hạ tầng cần thiết để đối với JPA, bạn có thể tiếp tục và chỉ cần viết mã như sau:
EntityManager em = … // obtain an EntityManager
JpaRepositoryFactory factory = new JpaRepositoryFactory(em);
UserRepository repository = factory.getRepository(UserRepository.class);
Lý do tôi đề cập đến điều đó một cách rõ ràng là cần phải nói rõ rằng, trong cốt lõi của nó, không có gì trong mã đó yêu cầu một vùng chứa Spring để chạy ngay từ đầu. Nó cần Spring như một thư viện trên classpath (vì chúng tôi không muốn phát minh lại bánh xe), nhưng nói chung là container bất khả tri.
Để dễ dàng tích hợp với các vùng chứa DI, tất nhiên, sau đó chúng tôi đã xây dựng tích hợp với cấu hình Spring Java, không gian tên XML, nhưng cũng có một phần mở rộng CDI , để Dữ liệu mùa xuân có thể được sử dụng trong các kịch bản CDI thuần túy.
@Repository
giao diện được chú thích ngay từ đầu không? Nhìn vàoRepositoryFactorySupport#getRepository()
cho thấy rằng nó lấy lớp giao diện làm tham số, vì vậy nó phải được phát hiện ở một nơi khác. Tôi đặc biệt đang cố gắng tìm ra cách tìm một giao diện có chú thích và tự động tạo một bean proxy JDK triển khai giao diện, rất giống với dữ liệu mùa xuân, nhưng cho mục đích ứng dụng cụ thể không liên quan đến Kho lưu trữ.