Communardo Software GmbH, Kleiststraße 10 a, D-01129 Dresden

Chuck Norris Component

Bei der Pluginentwicklung für Confluence benö­tigt man immer wie­der Zugriff auf  Komponenten, die ver­schie­dene Dienste bereit­st­sel­len. Dies kön­nen sowohl Komponenten aus dem Confluence-Kern, aber auch aus dem Plugin selbst, oder, seit dem Plugin-Framework V2, auch aus ande­ren Plugins sein. Zu die­sen Diensten gehö­ren z.B. die Bandana-Persistenz oder das Suchsystem. Confluence ver­wen­det den Spring-IoC-Container zur Verwaltung der Objekten zu die­sen Diensten und deren Abhängigkeiten zur Laufzeit.

Um im Plugin-Code Zugriff auf Spring-Beans zu erhal­ten gibt es zwei Möglichkeiten: Durch Spring-Autowiring oder über den ContainerManager von Confluence. Da man bei der Pluginentwicklung keine Spring-Konfiguration ver­wen­det, ist ein Teil der im Plugindescriptor ange­ge­be­nen Module (LINK) per Default auto­wired. Die dort inji­zier­ten Beans müs­sen dann an alle wei­te­ren Objekte über­ge­ben wer­den. Entweder im Construktor oder direkt beim Aufruf der Methoden, die deren Funktionalitäten benö­ti­gen. Dazu muss deren Aufruf aber von einem Objekt erfol­gen, dass Zugriff auf die benö­tigte Bean hat. Im Fall von Job-Modulen ist dies ein Problem: Der Job ist die erste auf­ge­ru­fene Komponente, wird aber nicht auto­wired. Somit kön­nen Beans nur noch über die 2. Variante refe­ren­ziert wer­den. Der ContainerManager ermög­licht über die Methode getComponent() Zugriff auf alle zen­tral regis­trier­ten Beans. Seit dem Pluginframework V2 sind dies aller­dings nur noch die Beans aus V1-Plugins und alle Beans aus dem Kern. Für fol­gende Beans geht dies nicht mehr:

1. alle Beans (Components) die im Context eines Plugins erstellt wur­den (Link!)

2. alle Beans die aus ande­ren Plugins impor­tiert wer­den (Component-Import) (siehe auch http://jira.atlassian.com/browse/CONF-20162)

Um die­ses Problem zu umge­hen, ver­wen­den wir in vie­len Plugins einen Plugin-lokalen ContainerManager. Dieser wird über ein Plugin Modul vom Typ Component rea­li­siert. Diese Component ent­hält Setter für alle benö­tig­ten Dienste und Manager. Dies kön­nen sowohl Beans aus den Standard-Kontexten von Confluence als auch sol­che aus dem Plugin oder aus ande­ren Plugins sein. Diese wer­den beim initia­li­sie­ren des Plugins in der Instanz der Component über Autowiring inji­ziert und kön­nen dann im Kontext des Plugins über diese Component refe­ren­ziert wer­den. Nun fehlt nur noch eine Möglichkeit auf die Instanz zugrei­fen zu kön­nen. Dazu wird sie einer Klassenvariable (sta­tic) der Component auf­ge­hängt. Dies kann z.B. durch Implementation des InitializingBean Interfaces gesche­hen. Das fol­gene Beispiel ver­deut­licht dies:

– Codebeispiel!!! mit Erläuterungen

Der Zugriff ist nun ziem­lich einfach:

23. Juli 2010

Pin It on Pinterest