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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With