Spring Boot 2.2.6中Kotlin配置类注入Java过滤器报NoClassDefFoundError
解决Spring Boot Kotlin配置类中自动装配Java自定义过滤器的NoClassDefFoundError问题
看起来你遇到的问题核心是Spring没有正确管理你的Java自定义过滤器,导致依赖注入失败或者类加载异常。结合你的代码和Spring Boot 2.2.6的特性,我整理了两种可行的解决方案:
方案一:将Java过滤器标记为Spring组件(推荐)
这个方法最符合Spring的依赖注入规范,让Spring全权管理过滤器的生命周期和依赖注入:
- 给
AuthTokenFilter.java添加@Component注解,让Spring扫描并管理这个类:
@Slf4j @Component // 新增注解,注册为Spring Bean public class AuthTokenFilter extends OncePerRequestFilter { @Autowired private JwtUtils jwtUtils; @Autowired private UserDetailsServiceImpl userDetailsService; // 原有方法保持不变 }
- 修改
SecurityConfig.kt,直接自动装配这个过滤器,不再手动创建:
class SecurityConfig : WebSecurityConfigurerAdapter() { @Autowired private val userDetailsService: UserDetailsServiceImpl? = null @Autowired private val unauthorizedHandler: AuthEntryPointJwt? = null @Autowired // 新增:自动装配Spring管理的过滤器实例 private val authTokenFilter: AuthTokenFilter? = null @Throws(Exception::class) override fun configure(auth: AuthenticationManagerBuilder) { auth.userDetailsService<UserDetailsService?>(userDetailsService).passwordEncoder(passwordEncoder()) } @Throws(Exception::class) override fun configure(http: HttpSecurity) { http.cors().and().csrf().disable() .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() .authorizeRequests().antMatchers("/api/auth/**").permitAll() .antMatchers("/api/users/**").permitAll() .anyRequest().authenticated() // 使用自动装配的过滤器,而非手动new http.addFilterBefore(authTokenFilter, UsernamePasswordAuthenticationFilter::class.java) } // 删除原来手动创建过滤器的@Bean方法 // @Bean // fun authenticationJwtTokenFilter(): AuthTokenFilter? { // return AuthTokenFilter() // } @Bean @Throws(Exception::class) override fun authenticationManagerBean(): AuthenticationManager? { return super.authenticationManagerBean() } @Bean fun passwordEncoder(): PasswordEncoder? { return BCryptPasswordEncoder() } }
方案二:手动注入过滤器依赖(适合不想标记@Component的场景)
如果你不想把过滤器注册为Spring组件,可以在创建过滤器实例时手动注入它的依赖:
- 修改
AuthTokenFilter.java,添加依赖的setter方法(去掉@Autowired,改为手动注入):
@Slf4j public class AuthTokenFilter extends OncePerRequestFilter { private JwtUtils jwtUtils; private UserDetailsServiceImpl userDetailsService; // 新增setter方法,用于手动注入依赖 public void setJwtUtils(JwtUtils jwtUtils) { this.jwtUtils = jwtUtils; } public void setUserDetailsService(UserDetailsServiceImpl userDetailsService) { this.userDetailsService = userDetailsService; } // 原有方法保持不变 }
- 在
SecurityConfig.kt中注入过滤器的依赖,并手动设置到过滤器实例:
class SecurityConfig : WebSecurityConfigurerAdapter() { @Autowired private val userDetailsService: UserDetailsServiceImpl? = null @Autowired private val unauthorizedHandler: AuthEntryPointJwt? = null @Autowired // 新增:注入过滤器需要的JwtUtils private val jwtUtils: JwtUtils? = null @Throws(Exception::class) override fun configure(auth: AuthenticationManagerBuilder) { auth.userDetailsService<UserDetailsService?>(userDetailsService).passwordEncoder(passwordEncoder()) } @Throws(Exception::class) override fun configure(http: HttpSecurity) { http.cors().and().csrf().disable() .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() .authorizeRequests().antMatchers("/api/auth/**").permitAll() .antMatchers("/api/users/**").permitAll() .anyRequest().authenticated() http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter::class.java) } @Bean fun authenticationJwtTokenFilter(): AuthTokenFilter? { val filter = AuthTokenFilter() // 手动注入依赖 filter.setJwtUtils(jwtUtils) filter.setUserDetailsService(userDetailsService) return filter } @Bean @Throws(Exception::class) override fun authenticationManagerBean(): AuthenticationManager? { return super.authenticationManagerBean() } @Bean fun passwordEncoder(): PasswordEncoder? { return BCryptPasswordEncoder() } }
额外检查点
如果以上方案还是解决不了问题,建议排查以下几点:
- 确保
JwtUtils和UserDetailsServiceImpl都被Spring正确管理(比如加了@Component/@Service注解),且Spring的包扫描范围覆盖了这些类所在的包。 - 检查构建工具(Maven/Gradle)的依赖是否完整,Spring Security相关依赖是否与Spring Boot 2.2.6兼容。
- 查看
NoClassDefFoundError的具体报错信息,确认缺失的类是什么,针对性排查类加载或编译问题。
内容的提问来源于stack exchange,提问作者Samat Abibulla
相关产品推荐
相关产品推荐

