Declarative Services i OSGi del 2

Genom att använda annotations med maven-scr-plugin kan man förenkla användande av OSGi-services ytterligare lite:

Sammanfattningsvis innebär förbättringarna att set-metoderna för tjänster ersätts med en annotering på medlemsvariabeln som håller tjänsteinstansen, och taggen Service-Component i pom.xml går bort.

Resultatet blir enkelt och elegant. Nedanstående exempelklass använder en service UpnpSniffer och när den finns tillgänglig anropas activate och där kan man direkt sätta igång och använda tjänsten:

import cag.labs.osgi.upnpsniffer.api.UpnpSniffer;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.osgi.service.component.ComponentContext;

@Component
public class UpnpStatusLog {
  @Reference
  private UpnpSniffer upnpSniffer;

  protected void activate(ComponentContext context) {
    String[] devices = upnpSniffer.getUpnpDevices();
    System.out.println("Devices: " + devices.length);
    for (String upnpDevice : upnpSniffer.getUpnpDevices()) {
      System.out.println(upnpDevice);
    }
  }
}

Via tjänsten UpnpSniffer, som i det här sammanhanget utgör en exempeltjänst, egalt vilken, sniffas alla device på det lokala nätet upp som implementerar UPnP-protokollet och i loopen skrivs deras namn ut.

Det som åstadkommer magin är annoteringarna. @Component är mandatory och @Reference anger var man vill att ramverket skall injekta en service-implementation. Dessa annoteringar gör att ramverket ser till att upnpSniffer initieras med en implementations-instans innan activate anropas. Man kan ange kardinalitet i anslutning till @Reference. Default (som ovan) är 1..1 (unary mandatory).

Om man istället (eller också) implementerar en tjänst annoterar man klassen med @Service, till exempel så här:

@Component
@Service
public class HelloImpl implements HelloService {
  public String sayHello(String name) {
    return "Hello " + name;
  }
}

Följande lägger man till i pom.xml:

  
        <dependency>
            <groupId>org.apache.felix</groupId>
            <artifactId>org.apache.felix.scr.annotations</artifactId>
            <version>1.6.0</version>
            <scope>provided</scope>
        <dependency>
...
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-scr-plugin</artifactId>
                <version>1.7.2</version>
                <executions>
                    <execution>
                        <id>generate-scr-scrdescriptor</id>
                        <goals>
                            <goal>scr</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
...

För att slutligen få det att kicka igång i t.ex. Knopflerfish måste man lägga till ett par bundlar explicit. Run-configuration i Intellij IDEA kan se ut så här:

Notera att man för att kunna köra inifrån aktuell version av Intellij 10.5.2 måste köra med näst senaste versionen av Knopflerfish: 3.1.0. Annars protesterar Osmorc pax runner.

Exempelkod finns att checka ut här: https://marell.se/svn/labs/osgi-labs.

IT Consultant at CAG Edge. Cloud and Continuous Delivery specialist, software developer and architect, Node.js, Java.

Publicerad i Java, OSGi

Kategorier

WP to LinkedIn Auto Publish Powered By : XYZScripts.com