Spring中同时使用@Bean和@Component注解注册Bean会出现什么问题?
问题根因
- 两种注册方式同时使用时,Spring容器中会生成两个相同类型的
UserDetailsService实例:- 加
@Service/@Component注解生成的实例,默认Bean名称为类名首字母小写的applicationUserService - 配置类中通过
@Bean方法生成的实例,Bean名称为方法名userDetailsService
- 加
- Spring Security的自动配置逻辑为:容器中仅存在单个
UserDetailsService类型Bean时,会自动将其作为认证数据源;如果存在多个同类型Bean且未指定优先注入实例,自动配置会兜底使用Spring内置的InMemoryUserDetailsManager(内存用户管理器,默认生成随机密码),你自定义的两个实现都不会被调用,因此看起来功能失效。 - 控制台不报错的原因是Spring Security本身提供了默认的兜底实现,不会触发缺少
UserDetailsService的异常,只是走了默认逻辑而非你自定义的逻辑。
解决方案
任选以下任意一种方案即可修复:
- 移除实现类上的
@Service/@Component注解,仅保留配置类中的@Bean注册方式 - 移除SecurityConfig中重写的
userDetailsService()方法的@Bean定义,仅保留实现类上的组件注解,Spring Security会自动识别这个唯一的自定义实现 - 如果确实需要保留两种注册方式,在你期望生效的
UserDetailsService实例上添加@Primary注解,指定该实例为优先注入的Bean,消除同类型Bean的注入歧义
内容的提问来源于stack exchange,提问作者TheOnly1
相关产品推荐
相关产品推荐

