Spring 拦截器和过滤器中自动注入为 null 的原因及解决方案

起因

开发过程中在过滤器(filter)中注入Bean出现空指针异常,通过查找资料了解空指针的原因,特此记录。

问题分析

由于其他bean在service,controller层注入一点问题也没有,开始根本没意识到Bean无法注入是在拦截器中无效的问题。

  1. SpringBoot项目的Bean装配默认规则是根据Application类所在的包位置从上往下扫描!
    “Application类”是指SpringBoot项目入口类。这个类的位置很关键:
    如果Application类所在的包为:com.root.app,则只会扫描com.root.app包及其所有子包,如果service或dao所在包不在com.root.app及其子包下,则不会被扫描!
    即, 把Application类放到dao、service所在包的上级,com.root.Application
    我出问题的类确实在Application类子包下面,排除此项。
  2. 意识到只是拦截器(或过滤器)上会有这样的问题,查询原因应该是:
    拦截器执行在自动bean初始化之前导致这个问题的。

Spring web中各个元素的初始化顺序

在web.xml中各个元素的执行顺序:

context-param–>listener–>filter–>servlet

而拦截器是在Spring MVC中配置的,如果从整个项目中看,一个servlet请求的执行过程就变成了这样:

context-param–>listener–>filter–>servlet–>interceptor(指的是拦截器)

为什么拦截器是在servlet执行之后,因为拦截器本身就是在servlet内部的。

元素具体概念

  • context-param:就是一些需要初始化的配置,放入context-param中,从而被监听器(这里特指org.springframework.web.context.ContextLoaderListener)监听,然后加载;

  • listener(监听器):就是对项目起到监听的作用,它能感知到包括request(请求域),session(会话域)和applicaiton(应用程序)的初始化和属性的变化;

  • filter(过滤器):就是对请求起到过滤的作用,它在监听器之后,作用在servlet之前,对请求进行过滤;

  • servlet:就是对request和response进行处理的容器,它在filter之后执行,servlet其中的一部分就是controller层(标记为servlet_2),还包括渲染视图层(标记为servlet_3)和进入controller之前系统的一些处理部分(servlet_1),另外我们把servlet开始的时刻标记为servlet_0,servlet结束的时刻标记为servlet_4。

  • interceptor(拦截器):就是对请求和返回进行拦截,它作用在servlet的内部,具体来说有三个地方:
    1)servlet_1和servlet_2之间,即请求还没有到controller层

    2)servlet_2和servlet_3之间,即请求走出controller层次,还没有到渲染时图层

    3)servlet_3和servlet_4之间,即结束视图渲染,但是还没有到servlet的结束

解决方案

  1. 使用WebApplicationContext 上下文对象来手动注入
  2. 在项目中继承“WebMvcConfigurerAdapter”类的类中添加拦截器类作为一个Bean(推荐)

问题原因

造成null的原因是因为拦截器加载是在springcontext创建之前完成的,所以在拦截器中注入实体自然就为null。

注入为null的时候,是通过new的方式创建的拦截器,通过new出来的实例是没有交给spring进行管理的,没有被spring管理的实例,spring是无法自动注入bean的,所以为null

参考连接:

  • https://blog.csdn.net/ycf921244819/article/details/91388440
  • https://www.cnblogs.com/shamo89/p/8534580.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/330233.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

kafka命令行生产者消费者测试

【README】 基于命令行开启生产者,消费者线程,测试kafka的消费转发功能; 【1】生产者与消费者 生产者201 [rootcentos201 logs]# kafka-console-producer.sh --topic first --broker-list centos201:9092 >hello-world >sichuan-c…

面象对象设计6大原则之五:依赖倒置原则

转载自 面象对象设计6大原则之五:依赖倒置原则依赖倒置原则(DIP),The Dependency Inversion Principle定义1、高层模块不应该依赖低层模块,两都应该依赖于抽象。2、抽象不依赖于具体细节。3、具体细节应该依赖于抽象。…

实现简单的注解型MVC框架 —— 低配SpringMVC

文章目录目标最终效果展示基本步骤1. 解析控制器类:2. 解析处理函数:3. 解析处理函数变量名:4. 监听TCP连接:5. 实现路由函数:知识点总结目标 与SpringMvc定义Controller类似效果 最终效果展示 主类 package org.e…

转:聊聊开发中幂等性问题(*)

【README】 这是一篇非常棒的, 讲解幂等性问题的post, 感谢原文作者; 转自: https://juejin.cn/post/6844903815552958477 幂等 (idempotence) 的概念 幂等的数学概念 幂等是源于一种数学概念。其主要有两个定义 如果在一元运…

面象对象设计6大原则之六:迪米特原则

转载自 面象对象设计6大原则之六:迪米特原则迪米特原则(LOD),The Law Of Demeter,也称为最少知识原则定义一个对象应该对其他对象有最少的了解。也就是说一个类耦合和调用一个类应该知道的最少,它只关心被耦…

转-Apache kafka 工作原理介绍

转自: https://developer.ibm.com/zh/articles/os-cn-kafka/ 消息队列 消息队列技术是分布式应用间交换信息的一种技术。消息队列可驻留在内存或磁盘上, 队列存储消息直到它们被应用程序读走。通过消息队列,应用程序可独立地执行–它们不需要知道彼此的…

Java内存区域(运行时数据区域)和内存模型(JMM)

原文作者:czwbig 原文:https://www.cnblogs.com/czwbig/p/11127124.html Java 内存区域和内存模型是不一样的东西,内存区域是指 Jvm 运行时将数据分区域存储,强调对内存空间的划分。 而内存模型(Java Memory Model&am…

kafka 学习 非常详细的经典教程

转自: https://blog.csdn.net/tangdong3415/article/details/53432166 一、基本概念 介绍 Kafka是一个分布式的、可分区的、可复制的消息系统。它提供了普通消息系统的功能,但具有自己独特的设计。 这个独特的设计是什么样的呢? 首先让我们看…

一个多线程死锁案例,如何避免及解决死锁问题

转载自 一个多线程死锁案例,如何避免及解决死锁问题 多线程死锁在java程序员笔试的时候时有遇见,死锁概念在之前的文章有介绍,大家应该也都明白它的概念,不清楚的去翻看历史文章吧。 下面是一个多线程死锁的例子 输出 thread1 get…

Thread打印值的含义

打印当前线程: log.warn("当前线程:"Thread.currentThread()");输出结果: 输出结果各部分的含义: Thread[ 线程名称, 线程优先级, 线程所属线程组 ]

WEB攻击手段及防御第1篇-XSS

转载自 WEB攻击手段及防御第1篇-XSS 概念 XSS全称为Cross Site Script,即跨站点脚本攻击,XSS攻击是最为普遍且中招率最多的web攻击方式,一般攻击者通过在网页恶意植入攻击脚本来篡改网页,在用户浏览网页时就能执行恶意…

转:权限管理——用户认证和用户授权

转自: https://blog.csdn.net/xdd19910505/article/details/51926540 因为做了权限的项目经理,so,恶补一下一个权限框架:shiro。其实作为框架首要目标是易于使用和理解。安全有时候是很复杂的,甚至是痛苦的&#xff0…

Spring websocket 使用@Autowired 出现null

问题 在spring websocket 中使用Autowired 出现空指针异常 原因 spring管理的都是单例(singleton),和 websocket (多对象)相冲突。websocket在客户端每建立一个链接就会创建一个新的对象,这个对象没有任何…

WEB攻击手段及防御第2篇-SQL注入

转载自 WEB攻击手段及防御第2篇-SQL注入 概念 SQL注入即通过WEB表单域插入非法SQL命令,当服务器端构造SQL时采用拼接形式,非法SQL与正常SQL一并构造并在数据库中执行。 简单的SQL注入的例子: 例1:test123456 or 11; …

WEB攻击手段及防御第3篇-CSRF

转载自 WEB攻击手段及防御第3篇-CSRF 概念 CSRF全称即Cross Site Request forgery,跨站点请求伪造,攻击者通过跨站点进行伪造用户的请求进行合法的非法操作,其攻击手法是通过窃取用户cookie或服务器session获取用户身份&#xff0…

Mybatis报错:nested exception is org.apache.ibatis.binding.BindingException: Parameter ‘XXX‘ not found

问题 使用Mybatis过程中报错 nested exception is org.apache.ibatis.binding.BindingException: Parameter XXX not found原因 mapper.xml映射没有得到传入的参数,当 SQL语句中只有一个参数时,mybatis可以正确传参,而如果由多个参数&…

java作为kafka生产者实验及Expiring超时问题解决

【README】 java作为生产者&#xff0c;centos 作为消费者&#xff1b; 【1】生产者代码 -- pom.xml <!-- 依赖 --> <dependencies><dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-clients</artifactId><…

WEB攻击手段及防御-扩展篇

转载自 WEB攻击手段及防御&#xff0d;扩展篇 之前的文章介绍了常见的XSS攻击、SQL注入、CSRF攻击等攻击方式和防御手段&#xff0c;没有看的去翻看之前的文章&#xff0c;这些都是针对代码或系统本身发生的攻击&#xff0c;另外还有一些攻击方式发生在网络层或者潜在的攻击漏洞…

java客户端作为kafka生产者测试

【README】 1、本文主要对 java客户端作为kafka 生产者进行测试&#xff0c; 消费者由 centos的kafka命令行线程扮演&#xff1b; 2、消息发送&#xff1a; kafka的生产者采用异步发送消息的方式&#xff0c;在消息发送过程中&#xff0c;涉及到2个线程——main线程和sender…

Redis学习之缓存穿透、缓存击穿和缓存雪崩详解

目录缓存穿透解决方案缓存空对象布隆过滤器缓存击穿解决方案对访问数据库的操作加锁提前缓存热点数据&#xff0c;设置热点数据永不过期缓存雪崩解决方案Redis高可用限流降级数据预热设置合理的过期时间参考缓存穿透 指的是对某个一定不存在的数据进行请求&#xff0c;该请求将…