Autowiring a Generic Implementation. Error: NoSuchBeanDefinitionException - java

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.

Rewrite the definition of List
#Service
public class CustomService {
#Autowired
private List<? extends CustomGenerator<? extends CustomClassA, ? extends CustomClassB>> customGenerators;
}
Spring will help to inject the list with ConcreteX bean.

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

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

Dependency Injection of Singleton Class that extends from Interface

I have a Singleton class ReadingStratgeyImp that extends from an Interface ReadingStrategy. In readingStrategyImp-getInstance() method will return the instance of ReadingStrategyImp.
Here is my query:
I want to inject the dependency of ReadingStrategyImp in a few of the other classes of the project.
I am achieving this by below code
ReadingStrategy readingStrategy;
#Autowired
public void setReadingStrategy(ReadingStrategyImp readingStrategy) {
this.readingStrategy = ReadingStrategyImp.getInstance();
}
I want to know how one will inject the dependency.
You simply do this :
#Component
public class Sample {
// spring will automatically find the implementation class and inject it.
// so, the ReadingStrategyImp class will automatically injected.
#Autowired
#Qualifier("readingStrategyImp")
private ReadingStrategy readingStrategy;
}
That's all.
If I understand your question correct, you should create first a Bean for ReadingStrategy with ReadingStrategyImp:
#Bean
public ReadingStrategy readingStrategy() {
return ReadingStrategyImp.getInstance();
}
Then you could just autowire the ReadingStrategy where you need it.
#Autowired ReadingStrategy readingStrategy;
Its always better to depend on interfaces not on concrete classes.

How to create a default overridable Component in Spring?

I am trying to create a Component that will be Autowired unless the user creates a different implementation.
I used the following code to try and isolate the problem:
The interface:
public interface A {...}
The implementation:
#Component
#ConditionalOnMissingBean(A.class)
public class AImpl implements A {...}
The usage code:
public class AUsage {
#Autowired
private A a;
}
In this example, I don't get AImpl autowired into AUsage.
If I implement A in another class without the ConditionalOnMissingBean it works.
I tried copying existing uses of #ConditionalOnMissingBean from the internet and noticed that they all reference a #Bean method.
Indeed, when I added this code to AUsage:
public class AUsage {
#Autowired
private A a;
#Bean
#ConditionalOnMissingBean
public A createA() {
return new AImpl();
}
}
and removed the annotations from AImpl:
public class AImpl implements A {...}
everything works as expected.
I'd be pleased to get an explanation to this, if anyone knows.

NoSuchBeanDefinitionException: No qualifying bean of type [duplicate]

This question already has an answer here:
What is a NoSuchBeanDefinitionException and how do I fix it?
(1 answer)
Closed 6 years ago.
I stack with above mentioned exception and really don't understate why it is appeared. I am using spring boot and declare bean through the annotation.
Application is executed by this class:
#SpringBootApplication
public class Application extends SpringBootServletInitializer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
My problem bean has the following declaration:
#Service
public class OrderSvc extends AbstractService implements DAOService {
I try to put it in the following bean:
#RestController
public class OrderController {
#Autowired
CarSvc carSvc;
#Autowired
OrderSvc orderSvc;
and the exception is appeared: Could not autowire field: biz.Services.OrderSvc biz.controllers.rest.administrator.OrderController.orderSvc; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [biz.Services.OrderSvc] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
I have also CarSvc bean that is located at the same package as OrderSvc and extends the same classes but there are no problems with it injection
#Service
public class CarSvc extends AbstractService implements DAOService<Car> {
Do you have any ideas why this exception appears ?
Spring creates proxies for classes that declare #Transactional, so that it is able to add the transactional behaviour and intercepted calls to your object. If the bean extends any interface Spring is going to create a Dynamic Proxy using the JDK Reflection API and this can only be done by interface. The proxy is a new object implementing the same interface. So your target bean is not your implementation but a proxy. That is why you were getting a non qualify bean exception.
CGLIB, on the other hand, can create a proxy by subclassing.
So, to get it working, you need to change your bean type to the interface or you can configure cglib using #EnableTransactionManagement(proxyTargetClass = true).
Try to to autowire your beans using interfaces rather than implementations :
#RestController
public class OrderController {
#Autowired
#Qualifier("carSvc")
DAOService carSvc;
#Autowired
#Qualifier("orderSvc")
DAOService orderSvc;
}
Edit : But before that you have to give names to your services :
#Service("carSvc")
public class CarSvc extends AbstractService implements DAOService<Car> {}
#Service("orderSvc")
public class OrderSvc extends AbstractService implements DAOService<Order> {}
What's going on here is that Spring generate proxies of your services based on the CarSvc, OrderSvc and implement the DAOService but does not extend the CarSvc, OrderSvc.
//somthing like this
class CarSvcProxy implement DAOService {
public Object getOrder(Long id) {
try {
// ...
txManager.commit();
} catch (Exception ex) {
txManager.rollback();
}
}
}
#RestController
public class OrderController {
//So when you do this :
#Autowired
CarSvc carSvc;
//it's somehow like if you did :
CarSvc carSvc = new CarSvcProxy(); //carSvc != CarSvcProxy
//But this will work :
DAOService carSvc = new CarSvcProxy(); //because CarSvcProxy implement DAOService
}
I found the code which leads to exception but I really don't undestand why.
In my OrderSvc there is the following method:
#Transactional(readOnly = true)
public Object getOrder(Long id) {
final Order order = getDAO().findOne(id);
OrderDTO orderDTO = modelMapper.map(order, OrderDTO.class);
return orderDTO;
}
So if the annotation #Transactional(readOnly = true) was excluded the application can be excecuted without problem... Do you have any ideas why this annotation lead to NoSuchBeanDefinitionException ?

Error creating bean because it's an interface?

Basically I have two beans implementing the same interface. One is for profile "default" and another "integration".
public interface SomeClientIfc { ... }
#Component
#Profile(value={"functional", "integration"})
public class StubSomeNIOClient implements SomeClientIfc {...}
public class SomeNIOClient implements SomeClientIfc {...}
#Configuration
#Profile("default")
public class SomeClientConfiguration {
#Bean
public SomeClientIfc someClient() {
...
SomeNIOClient someClient = new SomeNIOClient(numberOfParititions, controllerHosts, maxBufferReadSize,
connectionPoolSize);
return someClient;
}
}
In prod code it's
#Autowired
public SomeUserResolver(..., SomeClientIfc someClient) {...}
So far so good and I did see the stub bean is called in an integration test. Then I want to inject some test data into the stub bean in my integration test:
#ContextConfiguration(locations = {"/configProperties.xml", "/integrationTests.xml", ...})
#ActiveProfiles("integration")
public class SomeTestBase {
#Autowired
private SomeClientIfc someClientIfc;
}
However, when running the test I got error message
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'someClientIfc': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.audiencescience.some.client.SomeClientIfc]: Specified class is an interface
I even tried to replace SomeClientIfc with StubSomeNIOClient but still get the same message, even though StubSomeNIOClient is not an interface.
You should add a Qualifier annotation along with the Autowired one to specify which bean must be instantiated:
#Autowired
#Qualifier("my-bean")
The reason it's trying to inject the SomeClientIfc is because you called the variable 'someClientIfc'.
In the integration environment you have all 3 classes initialized: SomeClientIfc, StubSomeNIOClient, and SomeNIOClient. This creates a confusion for spring, luckily there are ways to resolve that confusion.
One way is as mentioned above by Little Santi, another way is to name your variable 'stubSomeNIOClient' see code below
#ContextConfiguration(locations = {"/configProperties.xml", "/integrationTests.xml", ...})
#ActiveProfiles("integration")
public class SomeTestBase {
#Autowired
private SomeClientIfc stubSomeNIOClient;
}

Issue with spring auto wiring with abstract class?

I have below abstract class.
Sender.java
public abstract class Sender{
public abstract void send(String id);
}
AttachSender.java
#Service("attachSender")
public class AttachSender extends Sender{
//It implements send() method here
}
SomeOtherClass.java
public class SomeOtherClass implements SomeOther{
#Autowired
private AttachSender attachSender;
}
Here i have an issue and the above code is not working.
My question is can i autowire the class instead of interface as above?
In my case AttachSender is a class but not interface.,
Thanks!
Yes, you can. If you have issues they should be elsewhere.
This thread deals with wiring a superclass, which might be of interest.
#service annotation looks wrong.
should be #Service

Categories