4 votes

Comment injecter une dépendance dans une classe de base du référentiel ?

Les différents @EnableXXXRepository Les annotations de Spring Data vous permettent de spécifier une classe de base personnalisée pour vos référentiels, qui sera utilisée comme implémentation des méthodes dans votre référentiel.

Si une telle classe de base a besoin d'accéder à d'autres haricots dans la classe ApplicationContext comment fait-on pour se les faire injecter ? Cela ne fonctionne pas d'emblée, car Spring Data instancie lui-même ces classes de base et ne prend en charge que les paramètres spéciaux des constructeurs dépendant du magasin.

Remarque : j'ai créé cette réponse dans le chat pour cette question maintenant supprimée et j'ai pensé que cela pourrait être utile à d'autres, bien que la question originale ait disparu.

6voto

Jens Schauder Points 23468

Dans le @Enable...Repository spécifient un repositoryBaseClass y repositoryFactoryBeanClass . Comme ça :

@EnableMongoRepositories(
    repositoryBaseClass = MyBaseClass.class,
    repositoryFactoryBeanClass = MyRepositoryFactoryBean.class)

Dans ce RepositoryFactoryBean vous pouvez utiliser l'injection de dépendance normale, car il s'agit d'un Spring Bean, donc, par exemple, vous pouvez obtenir une instance de SomeBean injecté via le constructeur, comme indiqué ci-dessous :

public class MyRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable> extends MongoRepositoryFactoryBean<T,S,ID>{

    private final SomeBean bean;

    public MyRepositoryFactoryBean(Class repositoryInterface, SomeBean bean) {
        super(repositoryInterface);
        this.bean = bean;
    }

}

Votre RepositoryFactoryBean crée maintenant une instance d'une RepositoryFactory en écrasant "getFactoryInstance".

@Override
protected RepositoryFactorySupport getFactoryInstance(MongoOperations operations) {
    return new MyMongoRepositoryFactory(operations, bean);
}

Ce faisant, il peut transmettre le haricot à injecter. bean dans l'exemple ci-dessus.

Et cette fabrique instancie finalement la classe de base de votre référentiel. La meilleure façon de procéder est probablement de tout déléguer à la classe de fabrique existante et d'ajouter simplement l'injection de la dépendance au mélange :

public class MyMongoRepositoryFactory extends MongoRepositoryFactory {

    private final SomeBean bean;

    MyMongoRepositoryFactory(MongoOperations mongoOperations, SomeBean bean) {
        super(mongoOperations);
        this.bean = bean;
    }

    @Override
    protected Object getTargetRepository(RepositoryInformation information) {
        Object targetRepository = super.getTargetRepository(information);
        if (targetRepository instanceof MyBaseClass) {
            ((MyBaseClass) targetRepository).setSomeBean(bean);
        }
        return targetRepository;
    }
}

Il existe un exemple complet et fonctionnel sur Github .

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