问题
The spring boot apps starts up, tomcat runs, and then it throws an error before finally dying.
Error
Running my app gives me this Autowired
error:
2016-07-29 02:18:24.737 ERROR 44715 --- [ restartedMain] o.s.boot.SpringApplication : Application startup failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'webSecurityConfig': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private myapp.MyUserDetailsService myapp.WebSecurityConfig.userDetailsService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [myapp.MyUserDetailsService] 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)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
Details
My Security configuration:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/register").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/")
.permitAll()
.and()
.logout()
.permitAll();
}
@Autowired
private MyUserDetailsService userDetailsService;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
}
MyUserDetails:
@Service
@Transactional
public class MyUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
public MyUserDetailsService() {
super();
}
@Override
public UserDetails loadUserByUsername(String userName)
throws UsernameNotFoundException {
User user = userRepository.findByUserName(userName);
if (user == null) {
return null;
}
List<GrantedAuthority> auth = AuthorityUtils
.commaSeparatedStringToAuthorityList("ROLE_USER");
String password = user.getPassword();
return new org.springframework.security.core.userdetails.User(userName, password,
auth);
}
}
You may find full source code at Git Repo
回答1:
I've tried your project at commit 3b9a6a2e
, and the error is actually different:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'webSecurityConfig': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private myapp.MyUserDetailsService myapp.WebSecurityConfig.userDetailsService; nested exception is java.lang.IllegalArgumentException: Can not set myapp.MyUserDetailsService field myapp.WebSecurityConfig.userDetailsService to com.sun.proxy.$Proxy80
Which makes your question a duplicate of Spring can't create beans. Solution: replace
@Autowired
private MyUserDetailsService userDetailsService;
with
@Autowired
private UserDetailsService userDetailsService;
Your solution (removing @Transactional
) works because without @Transactional
there is no reason for Spring to wrap MyUserDetailsService
in a proxy.
回答2:
Removing @Transactional
from MyUserDetailsService
worked. No idea why. If someone has an explanation, please post and it i'll mark it as the answer.
Double checked, this really is correct, if you'd like to check for yourself, please check out commit 840f0753bdca1592d9070c74bc87f30e8e2f87a7
for the repository listed above, and test it.
And stop downvoting this answer because you think it's incorrect.
回答3:
Add @ComponentScan
to WebSecurityConfig.
This should wire in MyUserDetailsService due to component scanning as it is annotated with @Service
.
A package name can be passed as a parameter to the annotation to set the scope of component scanning, for example:
@ComponentScan("com.company.team")
回答4:
please add Annotation: @ComponentScan("")
on main configuration class.
If you want to create bean/service for specific directory then you can give package path inside @ComponentScan("package.to.scan")
来源:https://stackoverflow.com/questions/38647002/autowire-doesnt-work-for-custom-userdetailsservice-in-spring-boot