For most of the applications, the use of OSGi Declarative Services for wiring components is more effective than the traditional lookup-based methods. But if we think about the programming model, there are some questions that need to be answered.
First, we have to decide, how to describe our components. We can choose between the standard way (XML descriptors referenced by the Service-Component property of the OSGi manifest) and Java annotations (requires a 3rd party API).
XML descriptors are great things, we can declare the provided and required interfaces of our components as well as their configuration properties and factories for instantiating more than one component of the same type. Nice and intuitive, but it comes with certain cost: we have to duplicate information (component and interface declarations, bind methods). This may lead to programming mistakes causing runtime errors like uninitialized components, null references, etc.
We can prevent duplication by annotating our Java classes with all the information the classes do not contain. We can mark provided interfaces and bind/unbind methods. Additionally, we have to provide ways for storing component configuration. For this task, we can use something like the Preferences Service or the Configuration Admin Service.
Using annotations, we can minimize the number of program faults caused by missing or inconsistent component descriptions.
As long as we are allowed to use annotations, this solution could be better. But be aware, annotations are polluting the POJO model, because of the coupling between the annotation API and our component.