Her şeyden önce, devam eden bir kod üretimi yok, bu da şu anlama geliyor: CGLib yok, bayt kodu üretimi yok. Temel yaklaşım, bir JDK proxy örneğinin, ProxyFactory
arabirimi desteklemek için Spring'in API'sini kullanarak programlı bir şekilde oluşturulması MethodInterceptor
ve örneğe yapılan tüm çağrıları kesip yöntemi uygun yerlere yönlendirmesidir:
- Depo özel bir uygulama bölümü ile başlatılmışsa ( ayrıntılar için referans belgelerinin o bölümüne bakın) ve çağrılan yöntem o sınıfta uygulanıyorsa, çağrı oraya yönlendirilir.
- Yöntem bir sorgu yöntemiyse (
DefaultRepositoryInformation
bunun nasıl belirlendiğine bakın), depoya özgü sorgu yürütme mekanizması devreye girer ve başlangıçta bu yöntem için yürütüldüğü belirlenen sorguyu yürütür. Bunun için, çeşitli yerlerde açıkça bildirilmiş sorguları tanımlamaya çalışan ( @Query
yöntemde, JPA adlı sorgular kullanarak) sonunda yöntem adından sorgu türetmeye geri dönen bir çözüm mekanizması mevcuttur . Sorgu mekanizması tespiti için bkz JpaQueryLookupStrategy
. Sorgu türetme için ayrıştırma mantığı şurada bulunabilir PartTree
. Gerçek bir sorguya yapılan mağazaya özgü çeviri, örn JpaQueryCreator
.
- Yukarıdakilerden hiçbiri uygulanmazsa, yürütülen yöntemin bir depoya özgü depo temel sınıfı (
SimpleJpaRepository
JPA durumunda) tarafından uygulanmış olması gerekir ve çağrı, bunun bir örneğine yönlendirilir.
Yönlendirme mantığını uygulayan yöntem durdurucu QueryExecutorMethodInterceptor
, yüksek seviyeli yönlendirme mantığı burada bulunabilir .
Bu proxy'lerin yaratılması, standart bir Java tabanlı Fabrika modeli uygulamasında kapsüllenmiştir. Üst düzey proxy oluşturma şurada bulunabilir RepositoryFactorySupport
. Mağazaya özel uygulamalar daha sonra gerekli altyapı bileşenlerini ekler, böylece JPA için devam edebilir ve aşağıdaki gibi kod yazabilirsiniz:
EntityManager em = … // obtain an EntityManager
JpaRepositoryFactory factory = new JpaRepositoryFactory(em);
UserRepository repository = factory.getRepository(UserRepository.class);
Bundan açıkça bahsetmemin nedeni, özünde, bu kodun hiçbirinin ilk etapta bir Spring konteynırının çalışmasını gerektirmediğinin anlaşılması gerektiğidir. Spring'e sınıf yolunda bir kütüphane olarak ihtiyaç duyar (çünkü tekerleği yeniden icat etmemeyi tercih ederiz), ancak genel olarak konteyner agnostiktir.
DI kapsayıcılarıyla entegrasyonu kolaylaştırmak için, daha sonra elbette, bir XML ad alanı olan Spring Java yapılandırmasıyla ve aynı zamanda bir CDI uzantısı ile entegrasyon oluşturduk , böylece Spring Data düz CDI senaryolarında kullanılabilir.
@Repository
Spring'in ek açıklamalı arayüzleri ilk etapta nasıl keşfettiğini açıklayabilir misin?RepositoryFactorySupport#getRepository()
Arayüz sınıfını bir parametre olarak aldığını göstermeye baktığımızda, başka bir yerde keşfedilmesi gerekir. Özellikle açıklamalı bir arabirimi nasıl bulacağımı ve otomatik olarak arabirimi uygulayan bir JDK proxy çekirdeğini nasıl oluşturacağımı anlamaya çalışıyorum, yay verilerine çok benzer, ancak Depolarla ilgili olmayan uygulamaya özel bir amaç için.