Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Providing DI methods in abstract classes

Tags:

java

osgi

bnd

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 :)

like image 682
christian.vogel Avatar asked Sep 11 '12 07:09

christian.vogel


People also ask

Can abstract class have dependency injection?

Any concrete class inheriting the abstract class should be instantiable with a constructor (if not abstract itself of course). But use of constructor is prohibited by Spring because any class that we instantiate this way cannot be taken in charge by Spring's automated dependency injection.

How are methods used in abstract class?

To declare an abstract method, use this general form: abstract type method-name(parameter-list); As you can see, no method body is present. Any concrete class(i.e. class without abstract keyword) that extends an abstract class must override all the abstract methods of the class.

Can abstract classes have methods?

An abstract class can have an abstract method without body and it can have methods with implementation also. abstract keyword is used to create a abstract class and method. Abstract class in java can't be instantiated.

Can we Autowire dependency in abstract class?

We can't use @Autowired on a constructor of an abstract class. Spring doesn't evaluate the @Autowired annotation on a constructor of an abstract class. The subclass should provide the necessary arguments to the super constructor.


1 Answers

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.

like image 111
BJ Hargrave Avatar answered Sep 28 '22 08:09

BJ Hargrave