Providing DI methods in abstract classes
Asked Answered
M

1

9

In most cases I have a lot of components which are having the same classes to be injected by an OSGi Declarative Service. The services will be used to execute some logic which is the same for all derived components. Therefore to avoid duplicated code it would be the best to use abstract classes. Is there any possibility to move the DI reference methods (set/unset) to an abstract class. I'm using Bnd.

For Example:

@Component 
public class B implements IA {
   private ServiceC sc;

   @Reference
   public void setServiceC(ServiceC sc) {
      this.sc = sc;
   }  

   public void execute() {
      String result = executeSomethingDependendOnServiceC();

      // do something with result
   }

   protected String executeSomethingDependendOnServiceC() {
      // execute some logic
   }     
}

@Component 
public class D implements IA {
   private ServiceC sc;

   @Reference
   public void setServiceC(ServiceC sc) {
      this.sc = sc;
   } 

   public void execute() {
      String result = executeSomethingDependendOnServiceC();

      // do something different with result
   }

   protected String executeSomethingDependendOnServiceC() {
      // execute some logic
   }      
}

I want to move the setter for ServiceC and the method executeSomethingDependendOnServiceC() to an abstract class. But how does it look like in OSGi in connection with Bnd annotation. Just annotate the class with @Component is not working, because A and D will create different instances of the abstract class and the @Component is alsp creating an instance.

Maybe someone experience the same problem and give me some advices how a workaround could look like. At least a best practice solution would be fine as well :)

Mcmillin answered 11/9, 2012 at 7:7 Comment(0)
V
5

The DS annotations must be on the class being instantiated for the component. Annotations on super classes are not supported. There is a proposal to change the in a future spec release.

What you can do is move the method to the super class, but you will need to trivially override the method in the subclass so that you can annotate it in the subclass.

Voidance answered 11/9, 2012 at 12:46 Comment(3)
Hi BJH. Thanks for your answer. I already thought about it, but I on the Apache Felix website for SCR annotation I found out that there is a flag componentAbstract for the Component annotation. See: felix.apache.org/site/… -> Abstract Service Descriptions. But there are no other information about this, even in the OSGi Sepcification. Do you know something about it?Mcmillin
I know the Felix DS guys are the one proposing support for "inheritance" of DS annotations. The annotations at the Felix link are the Felix proprietary annotations.Voidance
AFAIU, the Felix annotations using the maven-scr-plugin will simply merge the annotations of the abstract super class with the inheriting one at build time. Also, the OSGi spec did not standardize that as putting such an abstract component in your API (exported packages) is a bad idea as you will expose too much implementation detail and force a rebuild of all your inheriting components whenever you change @References etc. in the abstract base class.Rafat

© 2022 - 2024 — McMap. All rights reserved.