Control Dependency Injection in OSGI at Runtime (Binding/Resolving the Component to a Service at Runtime)
Use Case:
This can be achieved using any of the following three
methods depending upon our use case.
Options:
1)
Default mapping via Service ID
By Default System will do the
mapping to Service ID which is created First.
In the above example since the
Service Impl A is created First so it binds to A(Whose service ID is 8378 in
this case when compared to service id for Impl B which is 8380).
Refer below for Binding by Service
ID.
2)
Mapping using Service Ranking
In this option we can set specific
service Ranking for each of the component implementing the service as shown
below.In this case component implementation which has highest(Largest number) rank
gets invoked.
Example:
//Option 2 Binding by using Service Ranking which has highest Ranking
@ServiceRanking(1000)
public class SampleServiceAImpl implements SampleService {
//Option 2 Binding by using Service Ranking which has highest Ranking
@ServiceRanking(1001)
public class SampleServiceBImpl implements SampleService {
Note:
In the above example SampleServiceBImpl
will get invoked since it has the highest ranking when we invoke this osgi service
from another osgi service as shown below
import com.sandbox.core.services.SampleService;
import com.sandbox.core.services.InvokeService;
@Component(service = InvokeService.class,immediate = true)
public class InvokeServiceImpl implements InvokeService {
private static final Logger LOG= LoggerFactory.getLogger(InvokeServiceImpl.class);
//Option 2 Binding by using Service Ranking which has highest Ranking
@Reference
SampleService sampleService;
3)
Mapping using Target either via Component name
or property name
In this option we can invoke
specific implementation component either by
3a) Invoking by using target with Specific Component
Name
We can invoke
the specific implementation of Service Component by providing the name of the
component from the invoking service as shown below.In this case InvokeService
is the service from which we are calling the specific component implementation
import com.sandbox.core.services.SampleService;
import com.sandbox.core.services.InvokeService;
@Component(service = InvokeService.class,immediate = true)
public class InvokeServiceImpl implements InvokeService {
private static final Logger LOG= LoggerFactory.getLogger(InvokeServiceImpl.class);
//Option 3a Binding by using Service target via component name or Property Type
@Reference(target = "(component.name=com.sandbox.core.services.impl.DemoServiceAImpl)")
@Reference
SampleService sampleService;
3b) Invoking by using target with Component property
We can invoke
the specific implementation of Service Component by providing the property of
the component from the invoking service as shown below. In this case
InvokeService is the service from which we are calling the specific component
implementation.
Component
Implementation A
//Option 3 Binding by using Service target via component name or Property Type
@Component(service = SampleService.class,immediate = true,property = {"type=SampleServiceAImpl"})
public class SampleServiceAImpl implements SampleService {
Component
Implementation B
//Option 3 Binding by using Service target via component name or Property Type
@Component(service = SampleService.class,immediate = true,property = {"type=SampleServiceBImpl"})
public class SampleServiceBImpl implements SampleService {
Invoking the
above Implementation A or B from other service by using Property
import com.sandbox.core.services.SampleService;
import com.sandbox.core.services.InvokeService;
@Component(service = InvokeService.class,immediate = true)
public class InvokeServiceImpl implements InvokeService {
private static final Logger LOG= LoggerFactory.getLogger(InvokeServiceImpl.class);
//Option 2 Binding by using Service Ranking which has highest Ranking
@Reference(target = "(type=DemoServiceAImpl)")
@Reference
SampleService sampleService;
Reference Github Project:
https://github.com/rajashankar33/testrepo/tree/demoaemapp
Comments