Obtenez tous les haricots mise en œuvre d'une interface générique au Printemps
Comment puis-je obtenir une référence de tous les haricots mise en oeuvre de l'interface générique (par exemple, des filtres<TestEvent
>) dans le Printemps?
C'est ce que je veux atteindre avec un nombre minimum de lignes:
public interface Filter<T extends Event> {
boolean approve(T event);
}
public class TestEventFilter implements Filter<TestEvent> {
public boolean approve(TestEvent event){
return false;
}
}
public class EventHandler{
private ApplicationContext context;
public void Eventhandler(DomainEvent event) {
//I want to do something like following, but this is not valid code
Map<String, Filter> filters = context.getBeansOfType(Filter<event.getClass()>.class);
for(Filter filter: filters.values()){
if (!filter.approve(event)) {
return; //abort if a filter does not approve the event
}
}
//...
}
}
Mon actuel de la mise en œuvre utilise la réflexion pour déterminer si le filtre.approuver accepte de l'événement avant de l'appeler.
E. g.
Map<String, Filter> filters = context.getBeansOfType(Filter.class);
for(Filter filter: filters.values()){
if (doesFilterAcceptEventAsArgument(filter, event)) {
if (!filter.approve(event)) {
return; //abort if a filter does not approve the event
}
}
}
Où la doesFilterAcceptEventAsArgument fait tout le laid travail que je voudrais voudrais sortir de. Toutes les suggestions?
OriginalL'auteur Ola Herrdahl | 2010-07-12
Vous devez vous connecter pour publier un commentaire.
Si votre question est "est-Printemps ont une plus belle façon de le faire", alors la réponse est "non". Par conséquent, votre méthode ressemble à la omniprésent façon d'atteindre cet objectif (obtenir tous les haricots de la première classe, puis utiliser la réflexion pour regarder le générique de lie et de la comparer avec la cible de la classe).
En général, l'utilisation d'une information générique au moment de l'exécution est délicat et si possible à tous. Dans ce cas, vous pouvez obtenir le générique de limites, mais vous n'êtes pas vraiment faire beaucoup de bénéfice de la définition générique lui-même, d'autres que de l'utiliser comme une forme d'annotation pour vérifier manuellement.
Dans tous les cas, vous aurez à effectuer certains genre de vérification sur l'objet retourné, de sorte que l'original de votre bloc de code ne marchera pas; la seule variation est dans la mise en œuvre de
doesFilterAcceptEventAsArgument
. Le classique OO façon, serait d'ajouter un résumé de la superclasse avec deux méthodes comme suit (et ajouter celle-ci à l'interface de Filtre):C'est une sorte de douleur parce que vous aurez à mettre en œuvre le trivial
getEventClass()
méthodes dans chaque mise en œuvre pour le retour de la classe appropriée littérale, mais c'est une limitation connue de génériques. Dans les limites de la langue, c'est probablement le plus propre approche.Mais la vôtre est très bien pour ce que ça vaut.
OriginalL'auteur Andrzej Doyle
Juste pour la référence, la solution la plus simple que je pouvais construire:
Et cela a fonctionné assez bien pour le prototypage.
OriginalL'auteur Ola Herrdahl