Je travaille avec le référentiel Spring Data JPA dans mon projet depuis un certain temps et je connais les points ci-dessous:
findByCustomerNameAndPhone()
(en supposant que customerName
et phone
sont des champs dans l'objet de domaine).Je suis intéressé par la façon dont cela a été codé et j'ai examiné le code source et les API Spring JPA, mais je n'ai pas pu trouver de réponses aux questions ci-dessous:
Pourriez-vous s'il vous plaît aider avec les requêtes ci-dessus et également fournir toute documentation prise en charge?
Tout d'abord, il n'y a pas de génération de code en cours, ce qui signifie: pas de CGLib, pas de génération de code octet du tout. L'approche fondamentale est qu'une instance de proxy JDK soit créée par programme à l'aide de l'API ProxyFactory
de Spring pour sauvegarder l'interface et qu'un MethodInterceptor
intercepte tous les appels de l'instance et achemine la méthode aux emplacements appropriés:
DefaultRepositoryInformation
pour savoir comment cela est déterminé), le mécanisme d'exécution de la requête spécifique au magasin déclenche et exécute la requête dont l'exécution a été déterminée pour cette méthode au démarrage . Pour cela, un mécanisme de résolution est en place qui essaie d’identifier les requêtes explicitement déclarées à divers endroits (en utilisant @Query
sur la méthode, les requêtes nommées JPA) ont finalement recours à la dérivation de requête à partir du nom de la méthode. Pour la détection du mécanisme de requête, voir JpaQueryLookupStrategy
. La logique d'analyse de la dérivation de la requête se trouve dans PartTree
. La traduction spécifique du magasin dans une requête réelle peut être vue, par exemple. dans JpaQueryCreator
.SimpleJpaRepository
dans le cas de JPA) et l'appel est acheminé dans une instance de cette.L'intercepteur de méthode implémentant cette logique de routage est QueryExecutorMethodInterceptor
, la logique de routage de haut niveau peut être trouvée ici .
La création de ces mandataires est encapsulée dans une implémentation de modèle Factory standard Java. La création de proxy de haut niveau peut être trouvée dans RepositoryFactorySupport
. Les implémentations spécifiques à chaque magasin ajoutent ensuite les composants d'infrastructure nécessaires afin que, pour JPA, vous puissiez continuer et écrire simplement le code suivant:
EntityManager em = … // obtain an EntityManager
JpaRepositoryFactory factory = new JpaRepositoryFactory(em);
UserRepository repository = factory.getRepository(UserRepository.class);
La raison pour laquelle je le mentionne explicitement est qu'il devrait être clair que, dans son essence, rien de ce code n'exige qu'un conteneur Spring soit exécuté en premier lieu. Il a besoin de Spring en tant que bibliothèque sur le classpath (car nous préférons ne pas réinventer la roue), mais est agnostique au conteneur en général.
Pour faciliter l’intégration avec les conteneurs DI, nous avons bien sûr ensuite construit l’intégration avec Spring Java, un espace de noms XML, mais aussi une extension CDI , afin que Spring Data peut être utilisé dans des scénarios CDI simples.