101 votes

Compréhension de l'interface @NoRepositoryBean de Spring Data JPA

J'ai rencontré l'interface @NoRepositoryBean plusieurs fois en lisant la documentation de Spring Data.

Pour citer la documentation:

Si vous utilisez la détection automatique des interfaces de repository en utilisant l'espace de noms Spring, utiliser l'interface telle quelle causera à Spring de tenter de créer une instance de MyRepository. Ce n'est évidemment pas souhaitable car elle agit simplement en tant qu'intermédiaire entre Repository et les interfaces de repository réelles que vous souhaitez définir pour chaque entité. Pour exclure une interface étendant Repository de l'instanciation en tant qu'instance de repository, annotez-la avec @NoRepositoryBean.

Cependant, je ne suis toujours pas sûr de quand et où l'utiliser. Quelqu'un pourrait-il me conseiller et me donner un exemple concret d'utilisation?

192voto

Oliver Gierke Points 11630

L'annotation est utilisée pour éviter de créer des proxys de dépôt pour les interfaces qui correspondent effectivement aux critères d'une interface de dépôt mais qui ne sont pas censées en être une. Elle n'est requise que lorsque vous commencez à étendre tous les dépôts avec des fonctionnalités. Laissez-moi vous donner un exemple :

Supposons que vous souhaitiez ajouter une méthode foo() à tous vos dépôts. Vous commenceriez par ajouter une interface de dépôt comme ceci

public interface com.foobar.MyBaseInterface<…,…> extends CrudRepository<…,…> {

  void foo();
}

Vous ajouteriez également la classe d'implémentation correspondante, la fabrique, et ainsi de suite. Vos interfaces de dépôt concrètes étendraient désormais cette interface intermédiaire :

public interface com.foobar.CustomerRepository extends MyBaseInterface {

}

Supposons maintenant que vous amorcez - disons avec Spring Data JPA - de la manière suivante :

Vous utilisez com.foobar parce que vous avez CustomerRepository dans le même package. L'infrastructure de Spring Data n'a aucun moyen de savoir que le MyBaseRepository n'est pas une interface de dépôt concrète mais agit plutôt comme un dépôt intermédiaire pour exposer la méthode supplémentaire. Elle essaierait donc de créer une instance de proxy de dépôt pour celui-ci et échouerait. Vous pouvez maintenant utiliser @NoRepositoryBean pour annoter cette interface intermédiaire pour essentiellement dire à Spring Data : ne crée pas un bean proxy de dépôt pour cette interface.

Ce scénario est également la raison pour laquelle CrudRepository et PagingAndSortingRepository portent également cette annotation. Si l'exploration du package les a récupérés par erreur (parce que vous les avez configurés accidentellement de cette manière) l'amorçage échouerait.

En résumé : utilisez l'annotation pour éviter que les interfaces de dépôt ne soient considérées comme candidates pour finir par être des instances de bean de dépôt.

9voto

m.nguyencntt Points 580

Nous pouvons déclarer une nouvelle interface comme notre méthode personnalisée :

@NoRepositoryBean
public interface ExtendedRepository extends JpaRepository {
    List findByAttributeContainsText(String attributeName, String text);
}

Notre interface étend l'interface JpaRepository afin de bénéficier de tous les comportements standards.

Vous remarquerez également que nous avons ajouté l'annotation @NoRepositoryBean. Cela est nécessaire car sinon, le comportement par défaut de Spring est de créer une implémentation pour toutes les sous-interfaces de Repository.

public interface ExtendedStudentRepository extends ExtendedRepository {
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X