Warum CDI-Beans finale Methoden nicht unterstützen

7

Ich bin gerade in dem berüchtigten JavaEE CDI Fehler unter GlassFish Server aufgetreten:

%Vor%

Der Fehler ist ziemlich erklärend in der Tatsache, dass er finale Methoden in einer CDI-Bean nicht mag, aber ich kann nicht verstehen warum.

Unter diesem Link

Ссылка

Sie erklären, dass es etwas mit Serialisierung zu tun hat, aber ich kann nicht sehen, warum das Serialisieren einer Klasse mit einer finalen Methode schwieriger sein sollte als eines mit nicht finalen Methoden.

    
dendini 19.12.2013, 12:37
quelle

2 Antworten

12

Nun, es gibt verschiedene Möglichkeiten, ein Proxy-Objekt zu implementieren. Da Sie jedoch erwarten, dass der Proxy den gleichen Typ wie die Proxy-Bean hat, müssen Sie Vererbung (oder Anforderungsschnittstellen, die Sie dann implementieren können) verwenden, aber dies wäre kein Ansatz, bei dem jeder POJO eine Bean sein könnte CDI).

Das heißt, sie erstrecken sich intern von der Klasse, die Sie injizieren wollen, generieren einen Proxy-Code um diese und geben Ihnen diese Unterklasse.

Dieser Proxy behandelt dann die ganze Magie, um sicherzustellen, dass Sie immer eine Bean haben, die zu Ihrem Kontext passt (und diese Bean hat alle variablen Variablen-Beans, die auf die genau richtigen Beans zeigen).

Sie erhalten also nicht den Typ der Bean, die Sie injizieren möchten, sondern eine Proxy-Unterklasse dieser Bean. Dies funktioniert nicht sehr gut mit endgültigen Methoden und Klassen und privaten Konstruktoren.

Wenn die Klasse nicht final ist, kann der Proxy diese Klasse erweitern, aber die endgültige Methode kann nicht einfach überschrieben werden. Dies kann jedoch erforderlich sein (wenn beispielsweise Ihr Bean serialisiert ist, muss der Proxy es deserialisieren).

Dafür gibt es kompliziertere Wege. Man könnte diese Funktionalität injizieren, indem man den Byte-Code seiner Klasse über einen Agenten manipuliert (z. B. die letzten Modifikatoren entfernt, einen Standardkonstruktor einfügt, ...) und vielleicht sogar mit Vererbung mischt, aber dies ist noch nicht implementiert (und auch nicht trivial, um mehrere JVM-Implementierungen zu unterstützen).

Von der verknüpften Ressource eine Notiz, die angibt, dass dies für eine zukünftige Version geplant ist:

  

Hinweis

     

Eine zukünftige Version von Weld wird wahrscheinlich eine nicht standardmäßige Problemumgehung unterstützen   Für diese Einschränkung verwenden Sie nicht-portable JVM-APIs:       Sun, IcedTea, Mac: Unsicher.allocateInstance () (Die effizienteste)       IBM, JRockit: ReflectionFactory.newConstructorForSerialization ()

     

Aber wir haben das noch nicht umgesetzt.

    
Matthias 19.12.2013, 12:56
quelle
10

Container erstellt ein Proxy-Objekt für eingefügte Klassen. Container verwendet also nicht Ihre Klassen, sondern diese Klassen. Java prohibit erweitert die finalen Klassen, sodass Sie in CDI keine finalen Klassen verwenden können.

    
Fireworks 19.12.2013 12:42
quelle

Tags und Links