How to Fix Could not autowire. No beans of error in Spring Boot - spring-boot

How can I solve this error. I'm New to Spring-boot

As I can see the spring unable to find the bean UserDetailsServiceImpl, there might be couple of reason for it.
First, you might forgot to put #Service annotation on top of the class UserDetailsServiceImpl. Also, as the context is about Spring security so make sure that this class UserDetailsServiceImpl must implement the interface UserDetailsService
#Service
public class UserDetailsServiceImpl implements UserDetailsService {
}
Second, spring might be unable to scan this folder. So make sure spring IOC must scan this package while intialization and configure the bean.

In order to #Autowired a bean instance, a class should be decorated with Spring stereotype annotation like #Component, #Service, #Repository, #Controller or #Indexed. Just by decorating the class with one of these role annotations, you can use #Autowired to bind with the instance.
Otherwise, if none of these annotations are used, your class instances, you have to manually registered to the BeanFactory like this;
#Configuration
public class SomeClass {
...
#Bean
public UserDetailsServiceImpl userDetailsService() {
return new UserDetailsServiceImpl()
}
}
This answer just talk about your specific question, but you get to find out why #Configuration is used in preceeding example. Define scopes for bindings, singleton (one instance for the application) is the default scope in Spring, you should define scopes for beans if they should be in different scope on your requirements.

Related

Is the Rest Controller class singleton?

I am learning Spring and Spring Boot.
In my Spring boot app, I am using #RestController annotation for one of my classes which receives requests and processes them accordingly.
#RestController
public class SampleController {
......
}
I want to ask would this class annotated with #RestController be a singleton class?
My thought is that this SampleController would also be a bean and since the default scope is Singleton,
it would be a Singleton class. I want to ask whether I am thinking right.
Yes, you are right. Any bean you creating via annotations #Component, #Service, #Repository, #Controller, #RestController and #Bean of course by default have Singleton scope. Check
Bean scope

How SpringBoot dependency injection works with different type of annotations

I recently started exploring Spring Boot. I see that there are 2 ways to define Beans in Spring Boot.
Define #Bean in the class annotated with #SprinBootApplication
Define #Bean in a class annotated with #Configuration
I am also confused about stereo-type annotation #Repository #Service #Controller etc.
Can someone please explain how dependency-injection works with these annotations?
Yes it is possible.
Either you use #Bean in any of your #Configuration or #SpringBootApplication class or mark the bean classes explicitly with annotations like #Service, #Component #Repository etc.
#Service or #Component
When you mark a class with #Service or #Compoenent and if spring's annotation scanning scope allows it to reach to the package, spring will register the instances of those classes as spring beans.
You can provide the packages to be included/excluded during scan with #ComponentScan
#Bean
#Beans are marked on factory methods which can create an instance of a particular class.
#Bean
public Account getAccount(){
return new DailyAccount();
}
Now in you application you can simply #Autowire Account and spring will internally call its factory method getAccount, which in turn returns an instance of DailyAccount.
There is a simple difference of using #Bean vs #Service or #Compoenent.
The first one makes your beans loosely coupled to each other.
In the #Bean, you have flexibility to change the account implementation without even changing any of the account classes.
Consider if your classes instantiation is a multi-step operation like read properties values etc then you can easily do it in your #Bean method.
#Bean also helps if you don't have source code access to the class you are trying to instantiate.
Spring Boot auto-configuration attempts to automatically configure your Spring application based on the jar dependencies that you have added.
You need to opt-in to auto-configuration by adding the #EnableAutoConfiguration or #SpringBootApplication annotations to one of your #Configuration classes.
You are free to use any of the standard Spring Framework techniques to define your beans and their injected dependencies. For simplicity, we often find that using #ComponentScan (to find your beans) and using #Autowired (to do constructor injection) works well.
One way is to define #Bean in the class annotated with
#SprinBootApplication
If you see #SprinBootApplication it is combination of many annotation, and one of them is #Configuration. So when you define #Bean in the Main class, it means it's inside #Configuration class.
According to Configuration docs :
Indicates that a class declares one or more #Bean methods and may be
processed by the Spring container to generate bean definitions and
service requests for those beans at runtime.
class annotated with #Configuration
When you define #Bean is a class annotated with #Configuration class, it means it is the part of spring configuration all the Beans define in it all available for Dependency-Injection.
I have also seen some code where neither of the 2 above approaches
have been used and yet dependency injection works fine. I have tried
to research a lot on this but could not find any concrete answer to
this. Is this possible?
I am assuming you are talking about Sterio-type annotation. Every sterio type annotation has #Component, according to docs :
Indicates that an annotated class is a "component". Such classes are
considered as candidates for auto-detection when using
annotation-based configuration and classpath scanning.

Spring #configure annotation usage without bean definitions

I have some experience with spring dependency injection and transaction management but I am new to spring security. When i was reading an article related to spring security, I found that #Configuration annotation is used in an example but there were no bean definitions to be found.
According to my understanding, #Configuration annotation is used in classes which contain bean definitions. I need to know that what does the #Configuration annotation do in this example.
#Configuration
public class ApplicationSecurity extends WebSecurityConfigurerAdapter {
#Autowired
DataSource dataSource;
... // web stuff here
#Override
public configure(AuthenticationManagerBuilder builder) {
builder.jdbcAuthentication().dataSource(dataSource).withUser("dave")
.password("secret").roles("USER");
}
}
Thank you
It's not mandatory to have Bean definitions in Spring managed classes.
In this case #Configuration (which wraps #Component) is used to indicate to Spring that this class should be instantiated and all it's dependencies should be injected - in this case that's DataSource and AuthenticationManagerBuilder. This is an example of Inversion of Control principle.
Spring also provides these ConfigurerAdapter hook points, where you can tweak the default configuration of an already instantiated component.
This is exactly what is happening in your Configuration class.

#ControllerAdvice with #Autowired dependency not being injected

Anyone knows how to inject a dependency to a #ControllerAdvice?
My #ControllerAdvice extends Spring's ResponseEntityExceptionHandler and implements no interfaces.
The #ControllerAdvice gets called correctly, but the #Autowired dependency is never injected. There are no startup injection errors, the dependency is simply null.
I guess it has to do with how Spring proxies the #ControllerAdvice with cglib so that the #Autowired annotation gets lost.
I tested by implementing an interface, so that Spring could create a JDK proxy but it didn't work either. Actually with an interface, it didn't even gets called at all... even if I also annotate the interface with #ControllerAdvice.
Is there a way to specify that Spring should use JDK proxies for that particular case?
EDIT: I'm using Spring 3.2.4.RELEASE, by the way.
Sample class:
#ControllerAdvice
public class RestExceptionHandler extends ResponseEntityExceptionHandler {
#Autowired(required = true)
public AuditService auditService;
#ExceptionHandler(value = { RuntimeException.class })
public final ResponseEntity<Object> handleRuntimeException(Exception ex, WebRequest request) {
// auditService is null here!
}
}
In your case your bean is behind a CGLIB proxy.
It creates a subclass of your bean and as the method has final modifier it can't change the behavior of the original ResponseEntityExceptionHandler class to insert a call to the bean behind - please check my other answer about CGLIB.
CGLIB proxy is a different object that delegates the method calls to the original bean.
Please note that it would not be possible to implement much of Spring functionality only with subclassing i.e. without this separation of objects. How would it work when singleton-scoped bean references a session-scoped bean - obviously there are many session-scope beans and only one singleton-scoped bean.

Prevent autowiring by type for certain beans in Spring

In my spring context I am creating a service bean and a proxy for this service bean (explicitly). Both implement the same interface.
Can I ensure that autowiring cannot inject the target bean?
I would like to be able to use the target service with the #Resource or #Qualifier annotations, but when autowiring it should always be the proxy.
Any ideas?
Use the Primary annotation. It will indicate which bean should be use preferably when autowiring.
Hope this helps :)
You can put #Primary annotation in your proxy service like bellow:
#Primary
#Repository
public class ProxyOfSomeService implements SomeService
And after that when you use, #Autowired annotation on SomeService field, the ProxyOfSomeService will be injected by deafault.
But when you need the real service you can have it like bellow:
#Autowired
#Resource(name="someRealService")
private SomeService someService;
I think this serves your need, thanks!

Resources