2017-05-20 3 views
0

Ich habe einen OSGi-Bundle mit zwei Paketen:Methode Zugang und nicht exportierte Paket

  1. com.organization.api dieses Paket exportiert wird.
  2. com.organization.internal Dieses Paket wird nicht exportiert.

In com.organization.api Ich habe eine Schnittstelle Foo und Klasse AsbtractFoo

package com.organization.api; 

public abstract class AbstractFoo implements Foo { 

    private int state; 

    @Override 
    public int getState(){ 
     return this.state; 
    } 
} 

In com.organization.internal Ich habe eine Klasse FooManager, den Stand der Foo ändern muss. Wie man es mit der Bedingung macht, dass andere Klassen außerhalb com.organization.internal Status von foo nicht ändern können.

package com.organization.internal; 

public class FooManager { 

    private ???? foo = .... 

    public void updateFooState(){ 
     foo.????(); 
    } 
} 

Ich versuchte AbstractStatefullFoo mit Setter von Standardzugriffs (void setState(int state)) hinzuzufügen com.organization.internal zu verpacken und AbstractFooAbstractStatefullFoo erweitern zu machen, aber das Problem ist, dass dieser Fall andere Pakete benötigen Paket exportiert werden com.organization.internal.

Wie kann dieses Problem in OSGi gelöst werden?

Antwort

1

Ich habe das Gefühl, dass Sie denken, mit all diesen abstrakten Klassen zu komplex zu sein.

Der einfachste Fall ist, eine Schnittstelle Foo mit getState zu haben. Sie haben dann eine Implementierung von Foo im internen Paket.

Dieser Fall erfordert nicht, dass andere Bundles internen Zugriff auf die Impl-Klasse haben. Der wichtigste Punkt ist, eine Schnittstelle für FooManager im api-Paket zu haben.

Anschließend erstellen Sie FooManagerImpl, das den FooManager implementiert und als Dienst mit der Schnittstelle exportiert. Andere Bundles können dann diesen Dienst verwenden, um die updateState() -Methode und andere Methoden aufzurufen, die FooImpl-Klassen bearbeiten.

+0

Vielen Dank für Ihre Antwort, aber ich brauche wirklich abstrakte Klassen, da sie sehr viel Implementierung enthalten, die in konkreten Klassen in anderen Bündeln vererbt wird. –

+0

Sie können dies auch mit abstrakten Klassen dazwischen tun. Der Schlüssel besteht darin, einen OSGi-Dienst zu verwenden, und andere Bundles verwenden nur Klassen aus dem API-Paket. –

0

Erweiterung der vorherigen Antwort.

Etwas, das die Dinge für Sie vereinfachen könnte, ist, wenn Sie die wandelbar foo Zustand, kapseln und eine Fabrik als Service aus. Es kann sinnvoll sein, den foo manager service ab Werk zu haben, um sicherzustellen, dass sie synchron bleiben.

Die FooState Implementierung kann Methoden bieten, den Zustand zu ändern, die nicht in der Schnittstelle und welche privat zur Umsetzung Bundle enthält. Die FooState-Schnittstelle sollte als nicht für die Verbraucherimplementierung gekennzeichnet sein.

Die Foo-Schnittstelle kann geändert werden, um den Zugriff auf den FooState zu ermöglichen. Dieses Objekt ist schreibgeschützt (es sei denn, es wird eine Reflexion verwendet), ist jedoch nicht ordnungsgemäß unveränderbar. Sie können die Zugriffsmethode direkt zu Foo hinzufügen oder Sie können eine zusätzliche, exportierte Schnittstelle erstellen, um die Schnittstelle für API-Benutzer, die sich nicht darum kümmern, zu verkomplizieren. Die AbstractFoo-Implementierung kann in ein separates, exportiertes Paket verschoben werden. Dies kann nützlich sein, wenn die Standardimplementierung wahrscheinlich geschützte Methoden hervorbringt und sich in der Regel schneller ändert als die API selbst, so müssen Sie die Version der API nicht so häufig stoßen.

Die abstrakte Klasse kann darauf achten, einen FooState zusammen mit den anderen Implementierungsunterstützungstasks zu erhalten.

Es kann einige zusätzliche Komplikationen geben, wenn Sie die Manager-Implementierung aktualisieren können, ohne die Foos zu aktualisieren, aber dies scheint keine Anforderung zu sein.

Verwandte Themen