java - OSGi loose-coupling best practice -


i'd know considered best practices or patterns decoupling application code framework code, regarding osgi.

i'm going use example felix scr pages

the example service comparator

package sample.service; import java.util.comparator; public class samplecomparator implements comparator {     public int compare( object o1, object o2 )     {         return o1.equals( o2 ) ? 0 : -1;     } } 

the code above contains no framework plumbing, it's focused , concise. making available application, when using osgi, involves registering service registry. 1 way, described on felix pages linked, using service component runtime.

// osgi-inf/sample.xml <?xml version="1.0" encoding="utf-8"?> <component name="sample.component" immediate="true">   <implementation class="sample.service.samplecomparator" />   <property name="service.description" value="sample comparator service" />   <property name="service.vendor" value="apache software foundation" />   <service>     <provide interface="java.util.comparator" />   </service> </component> 

and

service-component: osgi-inf/sample.xml 

all nice , lovely, service implementation has no coupling @ osgi.

now want use service...

package sample.consumer; import java.util.comparator; public class consumer {     public void docompare(object o1, object o2) {         comparator c = ...;     } } 

using scr lookup strategy need add framework-only methods:

protected void activate(componentcontext context) {     comparator c = ( comparator ) context.locateservice( "sample.component" ); } 

using scr event strategy need add framework-only methods:

protected void bindcomparator(comparator c) {     this.c = c; }  protected void unbindcomparator(comparator c) {     this.c = null; } 

neither terribly onerous, though think it's probable you'd end fair amount of type of code duplicated in classes, makes more noise filter.

one possible solution can see use osgi specific class mediate between consumer, via more traditional means, , framework.

package sample.internal; public class osgidependencyinjector {     private consumer consumer;     protected void bindcomparator(comparator c) {         this.consumer.setcomparator(c);     }      protected void unbindcomparator(comparator c) {         this.consumer.setcomparator(null);     } } 

though i'm not sure how you'd arrange in scr configuration.

there org.apache.felix.scr.annotations, though means it'll work if you're building maven-scr-plugin. not bad and, afaict, impose no runtime implications.

so, you've read that, suggest best way of consuming osgi provided services without 'polluting' application code framework code?

1) not think bind methods polluting code, bean setters (you can call them setxxx more traditional). need unit testing well.

2) if use bnd (which in maven, ant, bndtools, eclipse plugin, etc) can use bnd annotations. bnd automatically create (always horrible) xml you.

package sample.service; import java.util.comparator; import aqute.bnd.annotations.component.*;  @component public class samplecomparator implements comparator {     public int compare( object o1, object o2 ) {         return o1.equals( o2 ) ? 0 : -1;     } }  @component class consumer {     comparator comparator;      public void docompare( object o1, object o2 ) {       if ( comparator.compare(o1,o2) )          ....     }      @reference     protected setcomparator( comparator c ) {        comparator = c;     } } 

in manifest, add:

service-component: * 

this picked bnd. no osgi code in domain code. might puzzled there no unset method default bnd static binding. set method called before you're activated , you're deactivated before unset called. long consumer object µservice too, you're safe. @ bndtools, bnd home page, , blogs more info µservices.

ps. sample invalid code because o1 answer both greater , lesser o2 if o1 != o2, not allowed comparator contract , make sorts unstable.


Comments

Popular posts from this blog

python - Scipy curvefit RuntimeError:Optimal parameters not found: Number of calls to function has reached maxfev = 1000 -

c# - How to add a new treeview at the selected node? -

java - netbeans "Please wait - classpath scanning in progress..." -