Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple Interface Implementations - AEM/CQ - OSGi

Tags:

osgi

aem

sling

There is an service interface HelloService, this is implemented by 2 Service implementations

HelloService Interface

public interface HelloService {
    public String getRepositoryName();
}

HelloServiceImpl1 implementation

@Service
@Component(metatype = false)
public class HelloServiceImpl1 implements HelloService {

    @Reference
    private SlingRepository repository;

    public String getRepositoryName() {
        return repository.getDescriptor(Repository.REP_NAME_DESC);
    }
}

HelloServiceimpl2 implementation

@Service
@Component(metatype = false)
public class HelloServiceImpl2 implements HelloService {

    public String getRepositoryName() {
        return "Response from HelloServiceImpl2";
    }
}

Now to use the service we use

@Reference
HelloService helloService;

Inside required method, call is made as

helloService.getRepositoryName();

I am getting response always from HelloServiceImpl1. Checked another example in AEM APIs, SlingRepository is extended by AbstractSlingRepository and AbstractSlingRepository2, how is the implementation picked internally, as while consuming we specify only @Reference SlingRepository repository;

How is this handled in AEM OSGi?


Update based on response

Checked on the syntax for this, following are observations

For using service ranking, use following with Service Implementation

@Properties({
    @Property(name = Constants.SERVICE_RANKING, intValue = 100)
})

For this no change in consumption, higher service ranking implementation is picked up, control is with provider

@Reference
HelloService helloService;

For using target filter, use following annotation to specify property

@Properties({
   @Property(name="type", value="Custom")
})

While consuming based on filter, specify target, control is with consumer

 @Reference (target="(type=Custom)")
 HelloService helloService;

If both service ranking and filter are used, filter is taking precedence.

like image 630
Sandeep Kumar Avatar asked Mar 22 '16 06:03

Sandeep Kumar


1 Answers

This is related to how Declaratives Services wires a @Reference. From the specification:

If the reference has a unary cardinality and there is more than one target service for the reference, then the bound service must be the target service with the highest service ranking as specified by the service.ranking property.

If there are multiple target services with the same service ranking, then the bound service must be the target service with the highest service ranking and the lowest service id as specified by the service.id property.

ie, it depends of the "Service Ranking" of the component. If this ranking is not specified, then you can have any implementations (you usually get the oldest service). You can use a filter if you want to target a specific implementation.

like image 142
Jérémie B Avatar answered Nov 16 '22 08:11

Jérémie B