Home > Software design >  Autowiring a Generic Implementation. Error: NoSuchBeanDefinitionException
Autowiring a Generic Implementation. Error: NoSuchBeanDefinitionException

Time:06-09

Below are the classes and the error mentioned. Spring version: 5

public interface CustomGenerator<T,R> {
  void generate();
}
@Service
public abstract class AbstractGenerator<T extends CustomClassA, R extends CustomClassB>
implements CustomGenerator<T,R> {}
@Service
public class ConcreteC1 extends AbstractGenerator<CustomClassA, CustomClassB>{

 void generate(){
  ...
 }
}
@Service
public class ConcreteC2 extends AbstractGenerator<CustomClassA, CustomClassB>{

 void generate(){
  ...
 }
}
@Service
public class CustomService {

@Autowired
private List<CustomGenerator<CustomClassA, CustomClassB>> customGenerators;
// Expected: ConcreteC1 & ConcreteC1 instances in the list

}

Error: org.springframework.beans.factory.UnsatisfiedDependencyException Unsatisfied dependency expressed through field 'customGenerators' nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type.

I want a list of concrete classes instead of utilizing qualifiers to pick one by one, as I want to execute the generate method for all the elements in the list at once. Thanks for any help in advance.

CodePudding user response:

Generic programming in java is not easy.
We can try to solve this by adding a base class for generic type.

class ConcreteBase extends AbstractGenerator<CustomClassA, CustomClassB> {
    ...
}

And rewrite our ConcreteX class:

class ConcreteX extends ConcreteBase {
    ...
}

After that, rewrite the type of List:

@Service
public class CustomService {
    @Autowired
    private List<ConcreteBase> customGenerators;
}

Spring will help to inject the list with ConcreteX bean.

CodePudding user response:

Tested this example as exactly as I could with version 5.3.2 and it seems to work for me.

Perhaps your problem is something different? Some follow up questions that might help getting to the bottom of it:

  • Are all the classes correctly configured in the component scan, for example?
  • Exact spring version info

CodePudding user response:

The below fix while autowiring made this silly mistake go away. Thanks, everyone for your time & responses :)

@Service
public class CustomService {

@Autowired
private List<CustomGenerator<? extends CustomClassA, ? extends CustomClassB>> customGenerators;

}
  • Related