将ApplicationScoped Bean注入Web Filter后对象为null的问题排查
问题原因与解决办法
你的AdminFilter使用了@WebFilter注解,这个注解属于Servlet规范范畴,默认由Servlet容器负责实例化和管理,并不受CDI容器管控,因此CDI的@Inject注解无法在这里生效,最终导致userService为null。
以下是几种可行的解决方法:
方法1:让Filter纳入CDI管理
给AdminFilter添加CDI作用域注解(比如@RequestScoped或@ApplicationScoped),同时保留@WebFilter注解,这样Servlet容器会将Filter的实例化权交给CDI容器,注入就能正常工作:
import javax.inject.Inject; import javax.servlet.Filter; import javax.enterprise.context.RequestScoped; import javax.servlet.annotation.WebFilter; @WebFilter("/admin/*") @RequestScoped public class AdminFilter implements Filter{ @Inject private UserService userService; // 实现Filter接口的doFilter、init、destroy方法 }
方法2:通过web.xml配置Filter并关联CDI管理
去掉@WebFilter注解,给Filter添加CDI作用域注解,然后在web.xml中手动配置Filter映射:
import javax.inject.Inject; import javax.servlet.Filter; import javax.enterprise.context.ApplicationScoped; @ApplicationScoped public class AdminFilter implements Filter{ @Inject private UserService userService; @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 业务逻辑处理 chain.doFilter(request, response); } // 实现init、destroy方法 }
对应的web.xml配置:
<filter> <filter-name>adminFilter</filter-name> <filter-class>你的包路径.AdminFilter</filter-class> </filter> <filter-mapping> <filter-name>adminFilter</filter-name> <url-pattern>/admin/*</url-pattern> </filter-mapping>
方法3:手动获取CDI Bean(临时方案,不推荐)
如果无法调整Filter的管理方式,可以在Filter的init方法中手动从CDI容器获取Bean实例,这种方式绕过了正常注入流程,不利于代码维护:
import javax.servlet.Filter; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.annotation.WebFilter; import javax.enterprise.inject.spi.CDI; @WebFilter("/admin/*") public class AdminFilter implements Filter{ private UserService userService; @Override public void init(FilterConfig filterConfig) throws ServletException { userService = CDI.current().select(UserService.class).get(); } // 实现doFilter、destroy方法 }
内容的提问来源于stack exchange,提问作者Sam Donato
相关产品推荐
相关产品推荐

