i was getting an issue which I couldn't understand, which was:
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of method setApplicant in webService.controller.RequestController required a bean of type 'com.service.applicant.Applicant' that could not be found.
Action:
Consider defining a bean of type 'com.service.applicant.Applicant' in your configuration.
I've done some researches but I still couldn't fixed this problem, when I simply removed the #ComponentScan from my Main Application Class and it worked.
I removed:
//#ComponentScan(basePackageClasses = AdminController.class)
Everything is fine, but i got curious... Can someone please help me?
When you don't use #ComponentScan explicity, #SpringBootApplication annotation on your main class has implementation of #ComponentScan in it(along with #EnableAutoConfiguration). So all the classes marked as #component(or similar annotation like controller, service etc.) get scanned automatically provided they are in the same or sub-package where main class is defined.
Now in your case you added //#ComponentScan(basePackageClasses = AdminController.class) in your main class. What this did that it only created bean for the class AdminController and ignored all other classes.
you should annotate the class Applicant with #Component first.
in your main class annotate the object with #Configuration, EnableAutoConfiguration and #ComponentScan({"com.service.applicant","your.admin.controller.path"}).
in the class RequestController annotate the property of type Applicant with #Autowire.
Related
I have an object of a class JwtApplicationTokenProvider I am injecting into my constructor:
private final JwtApplicationTokenProvider jwtApplicationTokenProvider;
#Autowired
public ClientPerformanceAnalyticsController(JwtApplicationTokenProvider jwtApplicationTokenProvider) {
this.jwtApplicationTokenProvider = jwtApplicationTokenProvider;
}
This class is part of a library I have imported via Maven and is fully qualified as com.garbage.mantis.jwt.application.JwtApplicationTokenProvider. In order to inform Spring of this bean I have added the package to #ComponentScan as so:
#ComponentScan({"com.garbage.wt.igip.gateway", "com.iggroup.mantis.jwt.application"})
When I try to run the application it fails with the error:
Field jwtApplicationTokenGenerator in com.garbage.mantis.jwt.application.configuration.JwtApplicationTokenGenerationConfiguration required a bean of type 'com.garbage.mantis.jwt.application.JwtApplicationTokenGenerator' that could not be found.
I can see this class does indeed exist but in another package in another library:
com.garbage.mantis.jwt.application.JwtApplicationTokenGenerator so when I try to add the package to the #ComponentScan list of arguments it fails with the same error:
#ComponentScan({"com.garbage.wt.igip.gateway", "com.garbage.mantis.jwt.application", "com.garbage.mantis.jwt.application.configuration"})
Field jwtApplicationTokenGenerator in com.iggroup.mantis.jwt.application.configuration.JwtApplicationTokenGenerationConfiguration required a bean of type 'com.iggroup.mantis.jwt.application.JwtApplicationTokenGenerator' that could not be found.
I have another application I have cloned which implements this and it runs without issue but I am unable to find what they have done to enable this. They don't even seem to pass the base packages in their #ComponentScan arguments.
What am I missing?
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/
Background: I am working in a project named com.x.myproject. I have the dependency of two other packages com.x.document and com.x.library. both packages have the same class with name QueueHelper.
Now, In my project, I have to scan one other package com.x.security which internally scans com.x, something like that:
#SpringBootApplication
#ComponentScan(basePackages = {"com.x"})
#EnableCaching
public class Security {
.......
}
in com.x.myproject
#SpringBootApplication
#ComponentScan(basePackages = {"com.x.myproject","com.x.security"}, excludeFilters={
#ComponentScan.Filter(type=FilterType.REGEX, pattern="com.x.document.*"),
#ComponentScan.Filter(type=FilterType.REGEX, pattern="com.x.library.*")})
public class MyProject{
.......
}
It all works fine when I use excludefilters in com.x.security but I want to use it in com.x.myproject
The exception which I got is
Annotation-specified bean name 'queueHelper' for bean class [com.x.library.utils.QueueHelper] conflicts with existing, non-compatible bean definition of same name and class [com.x.document.utils.QueueHelper]
Three answers come to my mind:
Give a different names to com.x.library.utils.QueueHelper and com.x.document.utils.QueueHelper via the #Component annotation. Spring will use the simple class name by default for naming the beans. You can annotate one with #Component('libraryQueueHelper') and the other with #Component('documentQueueHelper'). However, now you'll have to give a #Qualifier(<name>) in each place you're autowiring these beans.
Exclude them in your module, like you do in your question and then change their names using #Bean annotated methods within a #Configuration. When using in the third module, you'll need to use a #Qualifier to autowire the correct bean.
Rename the classes. This is the best solution in this case, but since you asked this question, I guess it's not viable.
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.
I encountered this issue when I'm trying to override the RibbonRoutingFilter bean defined in spring zuul. To emphasis, I'm doing an override, not just creating a bean of the same type. So end of the day, I want the "ribbonRoutingFilter" bean from zuul not registered at all.
So I have my own implementation. First thing I tried, I used the #component annotation and autowire the dependencies. Added a breakpoint in the constructor, and it ended up never being called. So I realize my definition must be loaded earlier than zuul's. So I created a configuration class with #Configuration annotation and #Order(Ordered.HIGHEST_PRECEDENCE), and use a #Bean annotation to instantiate my class there. Still, my method is always loaded earlier.
It turned out there's certain order Spring is following when loading configuration classes definitions and that is where overrides happen. Class org.springframework.context.annotation.ConfigurationClassParser has the detailed logic in method doProcessConfigurationClass(). I'll put my simplified summarization or the ordering rule here:
if you application class(where main() method is defined) has any classes defined in it, they are parsed and definition inside them are registered first
then it will registered Beans defined as #component and defined in #Configuration class
then it will add definitions introduced by #Import
then it will add definitions introduced by #ImportResource
then add definitions from #bean methods inside the application class
then from default methods on interfaces( I think it's java 8)
then try to do the same steps above for any parent classes you application class has extended.
This explained why my override was not working. It's because all I have been trying is in step 2. But zuul defined the bean by a #Import which is step 3.
So to solve my problem, I added a #Bean annotated method to my application class there and do the instanciation and the override just happend as expected.
The above summarization might not be accurate, it just give you an idea about what could have failed your override. You'd better debug the ConfigurationClassParser when you are trying your specific use case.