Ich verwende den folgenden Code:
%Vor%Wenn ich eine Anwendung auf Glassfish (Java EE 6 btw) veröffentliche, bekomme ich
AmbiguousResolutionException: WELD-001318 Cannot resolve an ambiguous dependency between (...) Car with qualifiers [@Any @Default] (...) Producer Method [Car] with qualifiers [@Any @Default]
Ich weiß, wenn ich @Alternative
zur Car-Klasse hinzufüge, wird es funktionieren, aber ich frage mich, ob dies der richtige Weg ist, und warum muss ich es tun?
Können Sie mir sagen, wie @Produces in diesem Fall richtig verwendet wird?
Ich benutze Java EE 6, CDI 1.0, EJB 3.1, Glassfish 3.2
Der Fehler kommt von der Tatsache, dass Sie zwei Beans vom Typ Car
haben, wobei einer die Klasse ist und der andere der Produzent. Sie haben zwei offensichtliche Lösungen, um die Mehrdeutigkeit zu beheben:
Zuerst setzen Sie die Logik hinter isBatmanCar
field in der ursprünglichen Klasse (z. B. in einem Konstruktor oder einer @PostConstruct
-Methode) und entfernen Ihren Producer. Das würde nur eine Car
Bean übriglassen.
Oder wenn Sie wirklich 2 Bean haben wollen oder es nicht vermeiden können, sollten Sie einen Qualifier für Ihre produzierte Bean erstellen:
%Vor%und benutze es auf Produzenten,
%Vor%um die Art des Autos injizieren zu können
%Vor% Qualifier ist die natürliche Option, um mehrdeutige Injektionen aufzulösen. Die Verwendung von @Alternative
funktioniert auch, aber es ist hier mehr ein Trick als eine gute Übung.
Letzte Bemerkung: @New
ist hier nicht notwendig, da Ihre Car
Bean keinen Geltungsbereich hat (also @Dependent
scoped). @New ist nur nützlich, wenn ein Producer eine Bean mit einem Bereich injiziert, der nicht @Dependent
ist. Das heißt, dieser Code ist nicht sehr nützlich, wenn Ihre Car
-Klasse im Bereich @Dependent
ist.
Die Verwendung von @Alternative funktioniert, sollte aber nur verwendet werden, wenn Sie es über beans.xml aktivieren möchten.
Das Unterdrücken des Standardkonstruktors Ihrer Bean funktioniert auch, aber Sie können Ihre Bean nicht in einem anderen Bereich als @RequestScoped verwenden.
Die Verwendung Ihres eigenen Qualifizierers funktioniert, ist aber nicht sehr nützlich, wenn Sie nur eine Implementierung haben und Ihre Bean nur mit einem Produzenten und nicht mit seinem Konstruktor instanziieren wollen.
Der einfachste Weg ist, Ihre Bean @ Anny mit Anmerkungen zu versehen:
%Vor%Dinge, die Sie beachten sollten:
Bei all dem sieht derselbe Code wie oben explizit so aus:
%Vor%Es wird offensichtlich, dass der Standardkonstruktor der Bean keine gültige Möglichkeit für den Injektionspunkt ist und der Hersteller eine gültige Möglichkeit darstellt.
Eine andere Möglichkeit wäre, einen nicht standardmäßigen Konstruktor in der Klasse Car zu erstellen:
%Vor%Durch Entfernen des Standardkonstruktors kann die Car-Klasse nicht mehr zum Erstellen von Instanzen verwendet werden, die durch Injektion verwendet werden.
Und ändern Sie Ihre Producer-Methode zu
%Vor%Dann wäre die Producer-Methode die einzige Möglichkeit, Ihre Autos zu erstellen.
Diese Methode kann verwendet werden, wenn Sie wissen, dass Sie immer eine benutzerdefinierte Instanz benötigen und keinen Standardkonstruktor benötigen. Aber normalerweise ist Antoine Lösung nützlicher.