Spring自定义OAuth2UserService无法自动装配UserRepository问题排查
自定义OAuth2UserService时@Autowired无法初始化userRepo,出现“lateinit property userRepo has not been initialized”错误
我正在尝试自定义OAuth2UserService以持久化自定义User实体,但调用loadUser方法时出现“lateinit property userRepo has not been initialized”错误,为何@Autowired无法初始化userRepo?
已执行的步骤:
- 自定义User实体
@Entity @Table(name = "users") class User( @Id var id: Long, var username: String )
- 自定义仓库
@Repository interface UserRepository: CrudRepository<User, Int>{ fun findUserByUsername(username: String): User? }
- 自定义服务
@Service class UserService : DefaultOAuth2UserService() { @Autowired lateinit var userRepo: UserRepository override fun loadUser(request: OAuth2UserRequest): OAuth2User { val oauth2User = super.loadUser(request) val user = userRepo.findUserByUsername(oauth2User.name) ?: throw UsernameNotFoundException(oauth2User.name) return CustomOAuth2User( user, oauth2User.authorities, oauth2User.attributes, oauth2User.name ) } }
- 配置代码
oauth2Login { oauth2 -> oauth2.userInfoEndpoint { endpoint -> endpoint.userService(UserService()) } }
问题根源
你在配置代码里直接通过UserService()手动实例化了UserService对象,这个对象不在Spring容器的管理范围内,Spring无法对其进行依赖注入,所以@Autowired标注的userRepo自然不会被初始化。
解决方案
要让Spring管理UserService实例,通过依赖注入的方式获取对象,而不是手动new。
方式一:字段注入UserService到配置类
@Autowired private lateinit var userService: UserService oauth2Login { oauth2 -> oauth2.userInfoEndpoint { endpoint -> endpoint.userService(userService) } }
方式二:构造函数注入UserService
@Configuration class SecurityConfig(private val userService: UserService) { @Bean fun filterChain(http: HttpSecurity): SecurityFilterChain { http { oauth2Login { oauth2 -> oauth2.userInfoEndpoint { endpoint -> endpoint.userService(userService) } } } return http.build() } }
额外优化:使用构造函数注入替代字段注入(Spring推荐)
修改UserService,用构造函数注入UserRepository,避免使用lateinit和@Autowired字段注入:
@Service class UserService( private val userRepo: UserRepository ) : DefaultOAuth2UserService() { override fun loadUser(request: OAuth2UserRequest): OAuth2User { val oauth2User = super.loadUser(request) val user = userRepo.findUserByUsername(oauth2User.name) ?: throw UsernameNotFoundException(oauth2User.name) return CustomOAuth2User( user, oauth2User.authorities, oauth2User.attributes, oauth2User.name ) } }
内容的提问来源于stack exchange,提问作者OffeeX
相关产品推荐
相关产品推荐

