You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@felix.apache.org by lksrules <lk...@gmail.com> on 2012/09/25 20:26:44 UTC

Dynamically referencing a Service using Felix annotations

I have created a interface . Which two different services are implementing .

Consider I have a interface named CheckReference and two different classes
CheckReferenceImpl1 and 
Check ReferencImpl2 .

@Component
@Service(value = CheckReference.class)
@Property(name = "domain", value = "ref1") 
public class CheckReferenceImpl1 implements CheckReference 

Also , 
@Component
@Service(value = CheckReference.class)
@Property(name = "domain", value = "ref2") 
public class CheckReferenceImpl2 implements CheckReference 

Now I want to dynamically load the implementation depending on my need using
@Reference annotation dynamically.
So , In a check condition 

public class LoadReference {
   @Reference
   CheckReference checkReference

   if(check) {
      // load checkReferencImpl1 
   } else {
      // load checkReferenceImpl2
   }
}

Also I know that I can use target property to load specific implemenation.
But that is static way.
But in order to do this dynamically , Not able to relate from specifications
and tutorials how should I do this ??






--
View this message in context: http://apache-felix.18485.n6.nabble.com/Dynamically-referencing-a-Service-using-Felix-annotations-tp4999472.html
Sent from the Apache Felix - Dev mailing list archive at Nabble.com.

Re: Dynamically referencing a Service using Felix annotations

Posted by David Jencks <da...@yahoo.com>.
On Sep 25, 2012, at 11:56 PM, Chetan Mehrotra wrote:

> Thanks David for those points!!
> 
>> You don't say which kind of annotations you are using (osgi ds, felix ds, or bnd ds).  I hope its osgi ds :-)
> Well I am used to Felix SCR annotation. Need to start using OSGi DS :)
> 
>> This will work fine.  However, you don't need the dynamic policy as long as all the CheckReference implementations are available before this manager component is created.
> But that is not easy to control ... so I typically default to Dynamic Policy
> 
>> Also, at least if you use bnd "next" for the annotation processing, you don't need to specify the spec version, bnd will figure it out for you.
> 
> Okie. I use Felix SCR Plugin so ther we need to specify that
> 
>> You might not want to instantiate the CheckReferenceImpls unless you actually want to use one of them.  In this case you can use bind/unbind methods taking a ServiceReference<CheckReference>  which will give you the properties you need to decide which one you want, and you can use
>> 
>> componentContext.locateService( "CheckReference", ref )
>> 
>> to get the actual service.
> 
> Good point. Delaying the service instantiation helps. Does
> componentContext.locateService perform an actual lookup everytime by
> querying the OSGi Service registry or it maintains a local copy of
> search results for subsequent calls for those service references.?

In trunk, at the moment, the first time you use locateService it will fetch the service object and cache it.  I think the released code does this too but I'm less sure.

thanks
david jencks

> 
> regards
> Chetan


Re: Dynamically referencing a Service using Felix annotations

Posted by Chetan Mehrotra <ch...@gmail.com>.
Thanks David for those points!!

> You don't say which kind of annotations you are using (osgi ds, felix ds, or bnd ds).  I hope its osgi ds :-)
Well I am used to Felix SCR annotation. Need to start using OSGi DS :)

> This will work fine.  However, you don't need the dynamic policy as long as all the CheckReference implementations are available before this manager component is created.
But that is not easy to control ... so I typically default to Dynamic Policy

> Also, at least if you use bnd "next" for the annotation processing, you don't need to specify the spec version, bnd will figure it out for you.

Okie. I use Felix SCR Plugin so ther we need to specify that

> You might not want to instantiate the CheckReferenceImpls unless you actually want to use one of them.  In this case you can use bind/unbind methods taking a ServiceReference<CheckReference>  which will give you the properties you need to decide which one you want, and you can use
>
> componentContext.locateService( "CheckReference", ref )
>
> to get the actual service.

Good point. Delaying the service instantiation helps. Does
componentContext.locateService perform an actual lookup everytime by
querying the OSGi Service registry or it maintains a local copy of
search results for subsequent calls for those service references.?

regards
Chetan

Re: Dynamically referencing a Service using Felix annotations

Posted by David Jencks <da...@yahoo.com>.
You don't say which kind of annotations you are using (osgi ds, felix ds, or bnd ds).  I hope its osgi ds :-)

This will work fine.  However, you don't need the dynamic policy as long as all the CheckReference implementations are available before this manager component is created.

Also, at least if you use bnd "next" for the annotation processing, you don't need to specify the spec version, bnd will figure it out for you.

You might not want to instantiate the CheckReferenceImpls unless you actually want to use one of them.  In this case you can use bind/unbind methods taking a ServiceReference<CheckReference>  which will give you the properties you need to decide which one you want, and you can use 

componentContext.locateService( "CheckReference", ref )

to get the actual service.

david jencks

On Sep 25, 2012, at 10:44 PM, Chetan Mehrotra wrote:

> You can use dynamic references
> @Component(...,specVersion="1.1")
> @References({
>        @Reference(
>                name = "CheckReference",
>                referenceInterface = CheckReference.class,
>                cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE,
>                policy = ReferencePolicy.DYNAMIC)
> })
> public class LoadReference {
> 
> And then have bind methods like
> 
> private Map<String,CheckReference> references = new
> ConcurrentHashmap<String,CheckReference>()
> 
> private void bindCheckReference(CheckReference ref,Map config) {
>        String domain = (String)config.get("domain");
>        references.put(domain,ref);
> }
> 
> private void unbindCheckReference(CheckReference ref,Map config) {
>        String domain = (String)config.get("domain");
>        references.remove(domain);
> 
> }
> 
> 
> And then in your implementation lookup the appropriate impl from the
> references map
> 
> Chetan Mehrotra


Re: Dynamically referencing a Service using Felix annotations

Posted by Chetan Mehrotra <ch...@gmail.com>.
You can use dynamic references
@Component(...,specVersion="1.1")
@References({
        @Reference(
                name = "CheckReference",
                referenceInterface = CheckReference.class,
                cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE,
                policy = ReferencePolicy.DYNAMIC)
})
public class LoadReference {

And then have bind methods like

private Map<String,CheckReference> references = new
ConcurrentHashmap<String,CheckReference>()

private void bindCheckReference(CheckReference ref,Map config) {
        String domain = (String)config.get("domain");
        references.put(domain,ref);
}

private void unbindCheckReference(CheckReference ref,Map config) {
        String domain = (String)config.get("domain");
        references.remove(domain);

}


And then in your implementation lookup the appropriate impl from the
references map

Chetan Mehrotra