Seiten

Mittwoch, 26. Juni 2013

CDI Commons – Dynamic Service Resolver

In meinem Blog über CDi und i18n (Artikel) hatte ich einen PropertyRegistryService vorgestellt.

Als Beispiel wurde der Producer für die Instanz eines SimpleDateFormat gezeigt.

image

Nicht schön war die harte Kopplung der Implementierung des PropertyRegistryService. Per Annotation wurde

die Implementierung deklariert. @CDIPropertyRegistryFileBased (im Blog noch @CDIFileBased)

Immer wieder muss aber zur Laufzeit entschieden werden welche Implementierung verwendet werden soll/muss.

Das kann verschiedene Gründe haben wie z.B. das derzeitige Lastverhalten, der angemeldete User und und und.

Wie also die Endscheidung vornehmen?

Zwei Dinge sind notwendig:

1) Das Interface der implementierenden Klasse, in unserem Fall PropertyRegistryService

2) und der Qualifier um den richtigen Producer zu selektieren.

image

 

Das Interface ist relativ leicht zu ermitteln. Mann kann es fest angeben, da man weiß das man genau dieses Interface benötigt.

Wenn auch das dynamisch ermittelt werden muss, kann man hier ähnlich wie bei den MessageRessourcen vorgehen. Es wird ein Key übergeben, der an anderer Stelle auf ein Interface gemappt wird. Hier einfach simuliert durch die Methode

Class mapp2Class(final String key)

Spannender wird es bei der Auswahl der richtigen Qualifiers. Das ist der Kern der Implementierung.  Simuliert wird es hier

durch die Methode resolveContextImpl(). Wie genau die Implementierung aussehen kann, hängt von der Umgebung ab und welche Parameter ausgewertet werden müssen.

Die Implementierung hier erzeugt ein AnnotationLiteral<CDIPropertyRegistryFileBased>. Das ist wieder eine harte Kopplung, kann jedoch wieder durch einen Mappingmechanismus zur Laufzeit aufgelöst werden.  Am einfachsten,  in dem man eine Klasse dynamisch instanziiert, die von AnnotationLitaral erbt.

z.B.

image