#5解析filter为什么不能注入bean和解决办法以及filter、interceptor、aspect之间的执行顺序

发布时间:2024年01月13日

1、定义

Filter可认为是Servlet的一种“变种”,过滤器可以拦截到方法的请求和响应,对请求响应做出过滤操作

Servlet是Java Web开发中的组件,它负责处理HTTP请求和响应。Servlet通常被用来处理业务逻辑,生成动态的HTML页面或者返回JSON数据等。

Interceptor是Spring MVC框架中的一种拦截器,它可以在请求到达Controller之前或者响应返回给客户端之前对请求或响应进行处理。Interceptor通常被用来做一些通用的处理,比如登录验证、权限验证、日志记录等。

Aspect切面是Spring AOP 操作的一种,可以对操作进行横向的拦截,最大的优势在于它可以获取执行方法的参数,对方法进行统一的处理。

其中Interceptor和Aspect均被SpringMVC管理,其核心是DispatcherServlet,继承自HttpServlet,因此从图中可以理解到,Filter和SpringMVC均存活在web容器中,具有平级的关系,只不过Filter在SpringMVC之前初始化。

2、Filter中为什么不能使用bean

由于Filter在SpringMVC之前加载,因此在Filter中注入的bean还没有被Spring容器进行加载,因此为null。

3、解决办法

3.1、使用Interceptor替代

当Spring容器将bean加载完毕后,在Interceptor中自然可以注入其他bean

3.2、使用DelegatingFilterProxy

DelegatingFilterProxy提供了 web容器和应用程序上下文之间的链接,在初始化期间,DelegatingFilterProxy 获取 filter-name 并从 Spring 应用程序上下文中检索具有该名称的 bean

DelegatingFilterProxy doFilter() 方法将所有调用委托给Spring bean,使我们可以在过滤器bean中使用所有Spring功能。

示例:

过滤器:

@Component("loggingFilter")
public class CustomFilter implements Filter {
    private static Logger LOGGER = LoggerFactory.getLogger(CustomFilter.class);

    @Override
    public void init(FilterConfig config) throws ServletException {
        // initialize something 
    }

    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
       HttpServletRequest req = (HttpServletRequest) request;
       LOGGER.info("Request Info : " + req);
       chain.doFilter(request, response);
    }

    @Override
    public void destroy() { 
    }
}

在web.xml中配置:

<filter>
	<filter-name>loggingFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>loggingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

或者通过配置类配置:

public class ApplicationInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected javax.servlet.Filter[] getServletFilters() {
       DelegatingFilterProxy delegateFilterProxy = new DelegatingFilterProxy();
       delegateFilterProxy.setTargetBeanName("loggingFilter");
       return new Filter[]{delegateFilterProxy};
    }
}

如果对你有帮助,点赞、收藏、关注是我更新的动力!

文章来源:https://blog.csdn.net/weixin_42718399/article/details/135517565
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。