Cannot Autowire interface in spring boot app - java

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.

Related

How to tell if a class is Spring loaded in java?

I have been given a task to assign a property from .properties file to a non Spring bean class using #Value annotation. To do this, I created a method on a #Component annotated class and set the property into it, then called that method from the non Spring bean class. I thought this would work, however, still showing as null.
I was told this is because the #Component annotated class I used is not spring loaded. Question, how can I tell if a class is Spring loaded bean? I have been searching on google but can't find anything helpful aside from examples with #Component or #Configuration annotations. Thanks.
Spring Container is responsible for creating or managing beans. It all satisfy the dependencies by injecting them either through constructor or setter method. But in your case you want the #Value injection in your non spring bean which is really not possible as per my understanding. Because here the spring does not creating the object then how it satisfy the dependencies of it.
You have two options for this situation.
Either annotate class using #Component
Either read property file using Properties
https://www.mkyong.com/java/java-properties-file-examples/

How does Java Spring #Autowired work with interface inheriting from several interfaces?

I have a Java Spring Framework project. After a bit of googling I found a way to include custom JPA methods into a JpaRepository. The injection of my repository into my service class using #Autowired works, but I can't understand how Spring handles the injection in this case. Could someone explain how Spring does the injection of CalendarEventRepository into CalendarEventService when the method implementations are in separate classes. It finds the JpaRepository implementation somewhere and my own custom implementation class with my custom method. Howcome their methods are accessible through the same reference variable calendarEventRepository? Bonus question: how does Spring find and instantiate the implementation for JpaRepository?
public interface CalendarEventRepository extends JpaRepository<CalendarEvent, Long>, CalendarEventRepositoryCustom { }
public interface CalendarEventRepositoryCustom {
public List<CalendarEvent> findCalendarEventsBySearchCriteria(CalendarEventSearchCriteria searchCriteria);
}
public class CalendarEventRepositoryImpl implements
CalendarEventRepositoryCustom {
public List<CalendarEvent> findCalendarEventsBySearchCriteria(CalendarEventSearchCriteria searchCriteria) {
}
}
public class CalendarEventService {
#Autowired
CalendarEventRepository calendarEventRepository;
...
calendarEventRepository.delete(calendarEvent);
...
return calendarEventRepository.findCalendarEventsBySearchCriteria(searchCriteria);
...
}
Thanks in advance!
When you are using Spring JPA repository interface (extend JpaRepository class), the important thing is that the implementation of the interface is generated at runtime. Method names are used by Spring to determine what the method should (since you have written the name findCalendarEventsBySearchCriteria correctly, it means that you already know that). In your particular case, CalendarEventRepository extends CalendarEventRepositoryCustom and therefore has a method findCalendarEventsBySearchCriteria(...), and also extends JpaRepository<CalendarEvent, Long>, which means that it should be treated as JPA repository, and the corresponding implementation should be generated.
To enable the generation of the repository implementation, you need to either include <jpa:repositories base-package="..." /> to your XML configuration file, or #Configuration #EnableJpaRepositories(basePackage = "...") When you have these, that's all the information Spring needs to generate (instantiate) repository and add it to application contexts, and the inject it into other beans. In your case, #Autowired CalendarEventRepository calendarEventRepository; specifies where it should be injected. I guess it more answers bonus question than the main one, but seems better to start with it.
I haven't yet touched CalendarEventRepositoryImpl. You should use such class if you want to drop the mentioned generation of repository implementation for particular methods. Spring looks for a class which name equals to repository interface's name + "Impl". If such class exists, Spring merges its methods with generated ones. So, see for yourself whether auto-generated findCalendarEventsBySearchCriteria method fits your needs or you want to implement it yourself. If the generated one fits, you should consider removing CalendarEventRepositoryImpl at all.
Could someone explain how Spring does the injection of
CalendarEventRepository into CalendarEventService when the method
implementations are in separate classes.
Answer: First, and most important - all Spring beans are managed - they "live" inside a container, called "application context".
Regardless of which type of configuration you are usin (Java or xml based) you enable "Component Scanning" this helps Spring determine which resource to inject.
How spring determines which bean to inject:
Matches the names.
Matches the type.
You even use Qualifiers to narrow down the search for spring.
It finds the JpaRepository implementation somewhere and my own
custom implementation class with my custom method. Howcome their
methods are accessible through the same reference variable
calendarEventRepository?
This is more of a java core question of inheritance. Since JpaRepository, CalendarEventRepositoryCustom and CalendarEventRepository are the base classes (implementations) of your CalendarEventRepositoryImpl so any method/field that is public or protected is available to CalendarEventRepositoryImpl class.
Here you are using "Program though interface" your reference variable here is calendarEventRepository which is an interface (parent) and that is why you are able to access the fields/methods.
Bonus question: how does Spring find and instantiate the
implementation for JpaRepository?
In spring configuration (java based) you tell spring to search for JPARepositories as below:
#EnableJpaRepositories(
basePackages = {
"com.package"}
, entityManagerFactoryRef = "EntityManagerFactory", transactionManagerRef = "jpaTransactionManager"
)
This is how spring gets to know which beans to create.
I recommend reading out Spring in Action (2nd to 4th Edition) by Craig Walls.
You can as well go through the https://spring.io/docs
Annotations (Autowired, Inject, your custom) works because of AOP. Read a bit about AOP and you will know how that works.

Autowiring an Interface fails

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/

Implementing Dependency Injection using Custom Annotation

I am working on a core java framework. I don't want to create instances directly inside the class which is why I want to use dependency injection.
I am thinking of declaring my custom annotations on the fields to be instantiated. And having a call back function which would create an instance and inject it into the field.
I had tried to create a custom annotation. But looks like there's no direct way to get a callback on the declared annotation. So, I was trying to scan the classes for that. But I ended up with this problem
Java Scanning Class for Annotation using Google Reflections
Please let me know if this is the right way of achieving this.
Since your question is tagged 'Spring', you can use Spring Framework's bean annotations (#Component / #Service / #Repository / ...), classpath scanning and #Autowired.
For example:
Setup classpath scanning on your spring config xml:
<context:component-scan base-package="com.mycompany.myapp" />
Create your bean to be scanned. Spring container will automatically create a singleton instance of this bean using default constructor:
#Repository
public class FooDAO {
...
}
Inject reference to above DAO instance using DI + autowiring
#Service
public class FooService {
#Autowired private FooDAO fooDAO;
...
}

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