Spring Security JDBC登录启动报UserDetailsService Bean注入失败异常
问题根因
抛出NoSuchBeanDefinitionException: 未找到UserDetailsService类型合格Bean的核心原因是:你自定义的UserDetailsService实现类LoginDetailsServiceImpl没有被注册到Spring IOC容器中,容器启动时找不到匹配的Bean给SecurityConfig注入。
查看代码可以直接定位到问题:LoginDetailsServiceImpl类上仅标注了@Transactional注解,没有添加任何Spring组件托管注解(@Service/@Component等),Spring组件扫描时会跳过这个类,不会将其实例化为容器Bean。
另外你的代码中还存在几个会引发后续运行异常的隐患,一并修复即可。
修复步骤
- 为
LoginDetailsServiceImpl添加组件注解
在类定义上方添加@Service注解,标记该类为Spring托管的Service层Bean,组件扫描时会自动识别并注册,同时补全方法重写标识和非空校验逻辑:
@Service // 新增该注解 @Transactional public class LoginDetailsServiceImpl implements UserDetailsService{ private final LoginRepo loginRepo; @Autowired public LoginDetailsServiceImpl(LoginRepo loginRepo) { this.loginRepo = loginRepo; } @Override // 补上重写注解,避免方法签名写错导致不生效 public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { Login login = loginRepo.findByUsername(username); if (login == null) { throw new UsernameNotFoundException("用户名或密码错误"); } // 权限集合参数不能传null,无权限配置时先传空集合 return new org.springframework.security.core.userdetails.User( login.getUsername(), login.getPassword(), new ArrayList<>() ); } }
- 确认组件扫描范围
检查SecurityConfig上@ComponentScan({ "com.xxxxx" })配置的根包路径,必须包含LoginDetailsServiceImpl、LoginRepo、LoginService这些类所在的包,如果类存放路径不在com.xxxxx及其子包下,需要补充扫描路径,否则加了注解也无法被扫描到。 - 统一使用容器中的密码编码器Bean
你已经在配置类中注册了BCryptPasswordEncoder的Bean,不要在configureGlobal方法中手动new新的实例,直接注入容器中的单例Bean使用:
@Autowired private BCryptPasswordEncoder bCryptPasswordEncoder; @Autowired protected void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService) .passwordEncoder(bCryptPasswordEncoder); }
验证
以上修改完成后重启项目,Spring会自动扫描到LoginDetailsServiceImpl并将其注册为UserDetailsService类型的Bean,完成SecurityConfig的依赖注入,原启动异常会直接消失。
内容的提问来源于stack exchange,提问作者user1712
相关产品推荐
相关产品推荐

