Seiten

Dienstag, 11. Juni 2013

CDI Commons – Param per Annotation

Heute geht es um die Möglichkeit in einer CDI Umgebung per Annotationen Parameter zu übergeben.
Als Beispiel nehme ich den SimpleDateFormatter. Typischerweise wird ein SimpleDateFormatter in der folgenden Form initialisiert.
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy:MM:dd hh:mm:ss");
Die erste Verbesserung hier ist die Verwendung einer zentralen Registry für die Definition der Pattern. ("yyyy:MM:dd hh:mm:ss"); Der Ausdruck selbst ist aber nicht kürzer und auch immer noch hart an die Registry gekoppelt. Der erste Ansatz per CDI ist dann ähnlich wie die Definition der Logger.
image
Die Annotation @CDICommons ist hier zur Abgrenzung zu den evtl. im ClassPath vorhandenen Implementierungen und Konstruktoren. Es empfhielt sich eine solche Annotation pro Modul zu verwenden. So können Mehrdeutigkeiten einfach gelöst werden. Die Annotation selbst ist schlicht aufgebaut.
image
Da die die Implementation SimpleDateFormat keinen Default-Konstruktor hat, ist es notwendig eine Erzeuger-Methode zu implementieren. Die Annotation @Produces ist hier das einzig auffällige.
image
Zu erkennen ist auch hier die Verwendung der konstanten Definition PATTERN. Zumindest im Quelltext ist nur noch an einer Stelle ein Verweis auf das Pattern selbst. Was aber, wenn man diese nun dynamisch zu Laufzeit ermitteln und verwenden möchte? Den Zugriff auf die jeweiligen Registries sollen nicht im gesamten Quelltext zu sehen sein.
Hier kann man den Weg über eine weitere Annotation gehen. Nennen wir sie @CDIRegEx.
image
Die Implementierung ist um die Definition eines Values angereichert worden. Das wichtige allerdings ist die darin verwendete Annotation @Nonbinding. Damit erst wird es möglich dieses Attribut zu verwenden, ohne das der CDI-Container versucht dieses Attribut für die Auflösung selbst zu verwenden. Wird diese Annotation nicht eingesetzt, kann der CDI-Container nicht mehr die vermeintliche Erzeuger-Methode finden.
 image
Die Erzeuger-Methode wird um die Annotation @CDIRegex in der Signatur erweitert. Innerhalb der Methode wird die Annotation selbst als Auslöser für die Initialisierung verwendet. In diesem Fall nur , indem das Pattern aus dem Attribut verwendet wird. An dieer Stelle kann dann allerdings der Zugriff auf die Registry erfolgen, damit zur Laufzeit dynamisch entschieden werden, welches Pattern zu Einsatz kommen soll.
Im Quelltext sind nun folgende Definitionen gültig, wobei die erste für eine Defaultinitialisierung verwendet wird.
image

Die Annotation CDIRegex kann auch in die Annotation CDICommons eingebettet werden. Das allerdings ist dann eher Geschmackssache, da der Code nicht reduziert wird.
image
image
Interessant ist allerdings, das nun alle drei vorgestellten Variablen-Definitionen gültig sind.
Das Beispiel ist wie üblich im Repository zu finden: Bitbucket - CDI-Commons