简体   繁体   中英

Multiple Interface Implementations - AEM/CQ - OSGi

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM