You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 2.2.6中Kotlin配置类注入Java过滤器报NoClassDefFoundError

解决Spring Boot Kotlin配置类中自动装配Java自定义过滤器的NoClassDefFoundError问题

看起来你遇到的问题核心是Spring没有正确管理你的Java自定义过滤器,导致依赖注入失败或者类加载异常。结合你的代码和Spring Boot 2.2.6的特性,我整理了两种可行的解决方案:

方案一:将Java过滤器标记为Spring组件(推荐)

这个方法最符合Spring的依赖注入规范,让Spring全权管理过滤器的生命周期和依赖注入:

  1. 给AuthTokenFilter.java添加@Component注解,让Spring扫描并管理这个类:
@Slf4j
@Component // 新增注解,注册为Spring Bean
public class AuthTokenFilter extends OncePerRequestFilter {
    @Autowired
    private JwtUtils jwtUtils;
    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    // 原有方法保持不变
}
  1. 修改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组件,可以在创建过滤器实例时手动注入它的依赖:

  1. 修改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;
    }

    // 原有方法保持不变
}
  1. 在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 11:33:14