Autowiring an Interface fails - java

I am using Spring MVC and Spring Integration in my application.
VendorService is my Interface whose implementation is taken care of by Spring Integration.
I am injecting VendorService's instance into my Controller by Autowiring it.
Here is my Controller..
#Autowired(required=true)
#Qualifier("vendorService")
VendorService vendorService;
I am getting the following error,
No qualifying bean of type [com.sample.service.VendorService] 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), #org.springframework.beans.factory.annotation.Qualifier(value=vendorService)}

I think you are not applying #Service or #Repository Annotations in your implementation class of interface (VenderService).
try this :-
#Repository
pulblic class VenderServiceImpl implements VenderService{
// Do your job here.
}
I hope it will work.

Spring can't find class which implements VenderService interface. Help him by adding #Service or #Component annotation to your class which implements VenderService.

The error indicates that Spring could not find an implementation of VendorService to satisfy your autowiring request. It can only use classes that implement the specified interface to do this, and they must either be defined in a context file, or found by package scanning (through the use of an annotation).

Here is good article on how spring loads beans in application context. Either you can manually define that as a bean using
1) <bean id="" class=""> in application context.
or if you want to annotate your calss then you have to add auto scanning of component using
2)<context:component-scan base-package="XX.XX" />.
This error occurs when spring can't find bean id in application context.
http://www.mkyong.com/spring/spring-auto-scanning-components/

Related

Cannot Autowire interface in spring boot app

I am developing a REST API using spring boot. Following is my package structure
Getting the following exception when I try to start my application
***************************
APPLICATION FAILED TO START
***************************
Description:
Field articleRepository in com.abc.service.ArticleService required a bean of type 'com.abc.dao.ArticleRepository' that could not be found.
Action:
Consider defining a bean of type 'com.abc.dao.ArticleRepository' in your configuration.
Following is my project structure-
com.abc
com.abc.bean
-Article.java
com.abc.controller
-ArticleController.java
com.abc.dao
-ArticleRepository.java (Interface)
com.abc.service
-ArticleService.java
com.abc.web
-AbcApplication.java (main Springboot class)
In AbcApplication.java as it is not in the root package, I have the below annotations
#SpringBootApplication
#ComponentScan(basePackages="com.abc.*")
I tried few ways -
I moved AbcApplication.java to root package com.abc but no success
Instead of interface(ArticleRepository.java) I made it a class, it is working
I keep it as interface but changed annotation from #Repository to #Service/Component still no success.
I am confused how it is working if I change it to class instead of interface.
#Repository
public interface ArticleRepository {
}
You don't have any bean for ArticleRepository. If you will use Spring Data Jpa you have to extend a type of Repository: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.
If you will use your own repository, you must implement it.
If you are using any RDBMS and if ArticleRepository repository is responsible for interacting with your database, then you need to either extends CrudRepository or JpaRepository in your ArticleRepository, then only Spring will be able to create the bean of ArticleRepository,and you will be able to autowire your repository.
If you are not extending any of CrudRepository or JpaRepository,then at the time of bean creation,ArticleRepository is only plain java interface and a plain interface can not be instantiated.
And as for your question:
Instead of interface(ArticleRepository.java) I made it a class, it is working
Its because when you declare it as a class, then Spring does instantiate a concrete class, so actual object will be created at the bean creation time and everything will be working as it should be.
Ideally you should have one class that implements interface ArticleRepository . Annotate that class with #Repository, spring will take care of wiring.
I was also encountered with the same issue. What I missed was the spring-boot-starter-jpa dependency. It worked when I added this dependency in the pom.xml file.
MyBatis gives you two samples to access your databases with spring boot.# Component or #Mapper.
Sample link:
mybatis-spring-boot-sample-xml
Suggestion:
Show your ArticleRepository code fully.
interface does not require any annotation (neither #repository not #Service).
If its a DAO file add #Repository annotation to the class implementing the corresponding interface.
And, if its a service then add #Service annotation to the class implementing the corresponding interface.

Some doubts about the use of **#Autowired** annotation and interface declaration in Spring Framework

I am quite new in Spring framework and I have some questions about the use of #Autowired annotation and interface declaration.
Referring to this example:
http://viralpatel.net/blogs/spring3-mvc-hibernate-maven-tutorial-eclipse-example/
I know that #Autowired annotation can be used to automatically link a bean on a property.
In the previous example I have the following situation:
I have a ContactDAO interface and it's implementation class named ContactDAOImpl
Next in the class ContactServiceImpl there is this variable annoted using #Autowired:
#Autowired
private ContactDAO contactDAO;
My first doubt is related to the fact that ContactDAO is an interface so what am I wiring? The concrete type: ContactDAOImpl ? If yes, is the Spring Framework that do it?
The second doubt is related to the fact that in the spring-servlet.xml configuration file there is not a bean definizion for the ContactDAO orf ContactAOImpl class...why? Is it because ContactDAOImpl class is annoted using #Repository annotation?
Thanks
Andrea
My first doubt is related to the fact that ContactDAO is an interface
so what am I wiring? The concrete type: ContactDAOImpl ? If yes, is
the Spring Framework that do it?
Spring will autowire an implementation of the interface for you, as long as there's only one matching implementation. There's also a way to match a single implementation from multiple candidates to your autowiring by using #Qualifier with #Autowired and naming the implementation.
The second doubt is related to the fact that in the spring-servlet.xml
configuration file there is not a bean definizion for the ContactDAO
orf ContactAOImpl class...why? Is it because ContactDAOImpl class is
annoted using #Repository annotation?
If you're using annotations (#Component, #Repository, #Service, #Controller) in your implementations for configuration, you don't need to explicitly define the bean in the xml (although you can do that also).
Edit: this old answer of mine might shed some more light about using annotations in Spring.
The answers to your two questions are Yes, and Yes.
In fact, you might not have an instance of ContactDAOImpl autowired in the service, but an instance of a proxy, which deletages to an instance of ContactDAOImpl. The proxy will typically handle transactions, translate exceptions, etc.
And the #Repository annotation is an alternative (simpler) way to declare a Spring bean. It works only if you have an element in the Spring xml file telling it to discover annotated beans.
Spring will autoscan all your classes and find all annotated classes and register them, this in your spring config will tell it to do that:
<context:component-scan base-package="my.base.package" />
Therefore you do not need to declare your #Repository in your configuration file.
Onto the first part of your question, this is the unpinning of the IOC pattern; your Service class is only aware of the interface of the DAO, this means that it is not dependent on the implementation.
During scanning Spring will find all of your annotated classes and when you ask for an #Autowired then it will attempt to find a class that your have annotated that is an implentor of the interface you have asked to have Autowired.
Have a look at the Spring documentation on Annotation Configuration.

Spring #Autowired - what is happening in the background

Excuse me if this is has already been discussed, I could not find a satisfying answer.
I do not understand whats happening when i create a bean in Springframework and #Autowired it to a field in another bean. I understand the result of #Autowired and other annotations but i do not know how its done by Spring.
class Sample1{
//
}
class Sample2{
#Autowired
Sample1 sample1Bean;
}
<bean id="sample1Bean" class="...Sample1"/>
<bean id="sample2Bean" class="...Sample2"/>
My question is how does spring set the field sample1Bean in Sample2? i am not expecting a complete explanation, but a direction where i have to look would be great. Thanks.
The #Autowired, #Inject annotations are resolved by a BeanPostProcessor - specifically AutowiredAnnotationBeanPostProcessor. This bean post processor intercepts the creation(for cases where #Autowired is on constructors) of beans, setting of property on the beans to ensure that all the autowired fields are appropriately set.
Im no expert in Spring but I will answer what I know. When a spring powered web application starts up, Spring framework goes through bean instantiation process in the application context. While creating beans Spring checks the required dependencies for a given bean. It looks up a matching bean based on the required type of bean and autowires it when #Autowired annotation is specified.
In the above example, Spring will go through application context and create a bean(object) of type Sample1. When it will construct bean Sample2 it sees #Autowiredannotation and will look for instantiated bean of type Sample1. When it finds bean of type Sample1 it will inject that bean on Sample2 and finish creating Sample2. This is called dependency injection and is one of the very popular features of Spring framework.
Hope this helps.

Can Spring's ObjectFactoryCreatingFactoryBean work with generics that refer to interfaces?

I'm using Spring's ObjectFactoryCreatingFactoryBean to retrieve a prototype scoped bean, as described in the Spring Documentation. Below is my applicationContext.
<bean id="exportFactory" class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean">
<property name="targetBeanName">
<idref local="export" />
</property>
</bean>
<bean id="export" class="com.someorg.ExportImpl" scope="prototype"/>
I autowire the exportFactory into a class like so:
#Autowired
#Qualifier("exportFactory")
private ObjectFactory<?> exportFactory;
And this works as expected. Each call to the exportFactory.getObject() method returns a new ExportImpl. On further inspect, a call to getObject() actually returns the following instance: org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean$TargetBeanObjectFactory
Now, ExportImpl is an implementation of an Export interface. And when I attempt to to declare the exportFactory using generics, described below, I get an exception.
#Autowired
#Qualifier("exportFactory")
private ObjectFactory<Export> exportFactory;
Stacktrace:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.someorg.Export] 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), #org.springframework.beans.factory.annotation.Qualifier(value=exportFactory)}
The application context successfully loads with this configuration, and the exception is thrown when I call exportFactory.getObject(). Using the same configuration I can successfully retrieve an instance of ExportImpl, so I know that bean is correctly wired.
I'd like to know a) what is Spring doing here and b) is there a reason I'm unable to use an ObjectFactory with type parameter that's an interface?
It turns out that ObjectFactoryCreatingFactoryBean is not necessary when you obtain ObjectFactory via #Autowired. In this case ObjectFactory for your bean is created automatically, though I can't find any reference of this behaviour in the documentation.
So, the behaviour you observe can be explained as follows:
When you write #Autowired #Qualifier("exportFactory") ObjectFactory<?>, Spring creates ObjectFactory that returns a bean named exportFactory, which itself is an ObjectFactory returned by the ObjectFactoryCreatingFactoryBean (its class is org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean$TargetBeanObjectFactory).
When you write #Autowired #Qualifier("exportFactory") ObjectFactory<Export>, Spring tries to find bean of type Export named exportFactory, and the search fails.
Change the qualifier to:
#Qualifier("export")

what are #Repository and #Autowired used for. (Spring)

I am learning java for 3 months and sometimes
i can not understand the usage purpose of something.
one topic was dependency injection and spring beans i figured out the finally =)
now i confused with the two annotations #Autowired and #Repository.
First What does Autowiring mean? then
Why should i use them and what is the difference between using them and not using?
Also today i tried to use hibernate in a spring mvc project and i had to search for about 15(cause of class not found errors) jar files beacuse of the dependencies of other jar files used in the project.
is this had to be this way? this makes learning java very hard for the beginners
thanks...
#Repository is an annotation that marks the specific class as a Data Access Object, thus clarifying it's role. Other markers of the same category are #Service and #Controller
#Autowired is an annotation with a completely different meaning: it basically tells the DI container to inject a dependency. More info at http://apollo89.com/java/spring-framework-2.5.3/api/org/springframework/beans/factory/annotation/Autowired.html
Edit
More info at tutorialpoint
or docs.spring.io
Both the annotations have different purposes to be used.
#Autowired: This is same as <bean="xyz" autowire="byType"> you define in the configuration file. The reference variable (dependency) that is annotated with #Autowired, will be injected by Spring container as any matching #Bean found in #Configuration class.
Plus the classes annotated with #Component, #Service, #Repository are too considered as beans so their objects are injected into the matching dependencies.
Spring container scans the beans in the classes you mentioned for "component-scan" or #ComponentScan("xyz").
#Repository: This is also a spring-framework's annotation. When you annotate a class #Repository, spring container understands it's a DAO class and translates all unchecked exceptions (thrown from DAO methods) into Spring DataAccessException.
DAO class is the class where you write methods to perform operations over db.
#Autowired and #Repository are very 2 different concepts.
1.# Repository: This define a class to be a repository, In general term you can use simply #Component but to define specifically, there are 3 more annotations like Controller,service and repository.Mainly 2 advantages:
1.If you have defined(context:component-scan)in servlet.xml to scan the defined package and find its own by spring.
2. More advantages you get from spring like database access error translation, so it is mainly defined to use with class in which you are connecting with database either with hibernate or jdbc.
#Autowired: to inject dependency at run-time by spring, means in a class, autowire a object ,and use it ,so this bean will automatically be made without defining in xml file

Categories

Resources