I would like to use ServiceTracker in order to consume the services published by our company. Instead of creating new ServiceTracker for each service I want to consume I thought it would be better to create just one with a filter and then get the services fro开发者_StackOverflow社区m it:
Filter filter = ctx.createFilter("(" + Constants.OBJECTCLASS + "=com.mycomp*)");
tracker = new ServiceTracker(ctx, filter, null);
The problem with this approach is that I then need to iterate over the service references the tracker had found examine their objectClass property and see if I can assign it to the service object which is very cumbersome and error prone due to casting that is required.
Any other ideas how to cunsume multiple services using more elegant way?
I think it is the wrong question :-) From the question I infer that you have a method that takes a service from your company and you want that method called. That is, somewhere in your code you need to be informed about a specific type com.mycomp.X, that is, you're not interested in general services from your company, you have a clear type dependency. In your question you assume that they need to be dispatched centrally which is usually not robust, error prone, and a maintenance hotspot; every time you have a new company service you need to update the dispatch method.
A MUCH better solution seems to be to use Declarative services and use bndtools with annotations. In that model, each place where you need service:
@Component public class SomeMyCompComponent {
...
@Reference
void foo( com.mycomp.X x ) { ... }
...
}
In this model, you do not need to centrally maintain a dispatcher, any class can get the services it needs when they need it. This model also accurately handles multiple dependencies and lots more goodies.
Maybe I do not understand the problem correctly because I inferred the problem from the solution you required. However, I think you try to abuse the Service Tracker for a task it was not intended to do.
Unfortunately, DS is not build into the framework as we should have done :-(
You could subclass ServiceTracker and add methods to provide direct access to the service types in which you are interested. For example, you could store the services in a typesafe heterogeneous container [1]. Then you would be able to call method on your ServiceTracker subclass which take the type of the service you are interested in and they could be easily looked up in the typesafe heterogeneous container.
[1] Effective Java, 2nd Ed., Item 29.
精彩评论