Control Dependency Injection in OSGI at Runtime (Binding/Resolving the Component to a Service at Runtime)

 


Use Case:

 As per regular pattern we bind a service interface for service implementation but there might be certain use cases for which we need to bind Service Interface to a Specific Implementation Class at run time as shown below. 



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 LOGLoggerFactory.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 LOGLoggerFactory.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 LOGLoggerFactory.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

Popular posts from this blog

Adobe AEM Maven Archetype 24 Error - java.nio.file.FileSystemException

Adobe AEM — How to Trigger Custom Workflow from Manage Publication(Manage Publish Wizard)

Direct integration Approaches with the Experience Cloud Identity Service