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

Spring Boot中Servlet Filter无法注入Bean的解决方法咨询

解决Spring Boot中Servlet Filter无法注入Bean的问题

问题根源

Servlet Filter默认由Servlet容器初始化,不属于Spring容器的管理范围,因此@Inject这类Spring依赖注入注解无法生效,导致AService无法被注入。

解决方案

方案一:将Filter交由Spring管理并通过FilterRegistrationBean注册

这是最规范的做法,让Spring负责Filter的实例化和依赖注入。

  1. 在你的依赖应用中,给MyFilter添加Spring组件注解:
import javax.inject.Inject
import javax.servlet.Filter
import javax.servlet.FilterChain
import javax.servlet.ServletRequest
import javax.servlet.ServletResponse
import org.springframework.stereotype.Component

@Component
class MyFilter : Filter {
    @Inject
    private lateinit var aService: AService

    override fun doFilter(request: ServletRequest, response: ServletResponse, chain: FilterChain) {
        aService.abc()
        chain.doFilter(request, response)
    }

    // 实现Filter接口的init、destroy方法,可留空实现
    override fun init(filterConfig: javax.servlet.FilterConfig?) {}
    override fun destroy() {}
}
  1. 在引入该依赖的主应用Java配置类中,用FilterRegistrationBean注册Filter:
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.yourpackage.MyFilter;

@Configuration
public class FilterConfig {

    @Bean
    public FilterRegistrationBean<MyFilter> myFilterRegistration(MyFilter myFilter) {
        FilterRegistrationBean<MyFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(myFilter);
        // 设置Filter匹配的URL路径,按需调整
        registrationBean.addUrlPatterns("/*");
        // 设置Filter执行顺序(可选)
        registrationBean.setOrder(1);
        return registrationBean;
    }
}

Spring会自动注入MyFilter实例,其内部的AService也会被正确注入。

方案二:手动通过WebApplicationContext获取Bean

如果必须由Servlet容器直接初始化Filter,可以手动从Spring上下文获取Bean:

修改MyFilter的doFilter方法,缓存获取到的Bean避免重复查询:

import javax.servlet.Filter
import javax.servlet.FilterChain
import javax.servlet.ServletRequest
import javax.servlet.ServletResponse
import org.springframework.web.context.support.WebApplicationContextUtils

class MyFilter : Filter {
    private var aService: AService? = null

    override fun doFilter(request: ServletRequest, response: ServletResponse, chain: FilterChain) {
        if (aService == null) {
            // 获取Spring Web上下文
            val context = WebApplicationContextUtils.getWebApplicationContext(request.servletContext)
            // 方式1:按类型获取Bean(推荐,无需记忆Bean名称)
            aService = context?.getBean(AService::class.java)
            // 方式2:按名称获取Bean,@Service默认的Bean名称是首字母小写的类名,即aServiceImpl
            // aService = context?.getBean("aServiceImpl") as AService?
        }
        aService?.abc()
        chain.doFilter(request, response)
    }

    override fun init(filterConfig: javax.servlet.FilterConfig?) {}
    override fun destroy() {}
}

注意事项

  • 若AService存在多个实现类,需通过@Qualifier注解或明确指定Bean名称/类型来区分。
  • 采用方案一时,要确保主应用能扫描到依赖应用中的@Service和@Component,可通过@ComponentScan指定依赖应用的包路径。

内容的提问来源于stack exchange,提问作者Josh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 00:53:15