SpringMVC控制层private方法中出现注入的service对象空指针异常
一、现象
SpringMVC中controller里的private接口中注入的service层的bean为null,而同一个controller中访问修饰符为public和protected的方法不会出现这样的问题。
controller中的方法被AOP进行了代理,普通Controller如果没有AOP,private方法中bean也是正常的。
二、原因分析
因为没有AOP增强的private方法是正常的,所以我们可以联想到可能是因为创建了代理对象的原因导致的属性为空。
首先SpringAOP有两种实现方式,一种是Jdk动态代理,一种是Cglib动态代理。
这两种方式一种是通过对接口的实现,一种是通过创建子类重写,那么显然这两种方式都是无法代理私有方法的。
创建代理对象时会经过这么一段逻辑Enhancer#generateClass -> Enhancer#getMethods -> CollectionUtils.filter(methods, new VisibilityPredicate(superclass, true)) -> VisibilityPredicate#evaluate
public boolean evaluate(Object arg) {Member member = (Member)arg;int mod = member.getModifiers();if (Modifier.isPrivate(mod)) {return false;} else if (Modifier.isPublic(mod)) {return true;} else if (Modifier.isProtected(mod) && this.protectedOk) {return true;} else {return this.samePackageOk && this.pkg.equals(TypeUtils.getPackageName(Type.getType(member.getDeclaringClass())));} }可以看到其中将私有方法进行了过滤,即创建的代理对象中并不会增强private方法
Spring中使用@Aspect注解会注册一个后置处理器,在Bean初始化时判断是否需要创建代理(主要逻辑在wrapIfNecessary方法中)。而我们都知道Bean在属性赋值时便将属性的依赖都注入了,所以此时的Bean中service层的bean是完成填充了的。
那为什么会出现调用private方法空指针异常呢?
这是因为为该类创建的代理并没有完成bean的生命周期,所以其中的属性是null。private方法并没有被真正的代理类拦截(如前面所说被过滤了),因此private方法无法获取被代理的对象,所以使用的是代理对象去调用的方法,而代理对象是由Cglib创建的并没有注入bean对象,所以出现了空指针异常。
而当调用被增强了的方法(即在代理类中重写了的方法)时,其实传入的并非代理的实例对象,而是target,即被代理的Bean的实例对象,所以才能取得service层的bean。
private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {@Override@Nullablepublic Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {// 省略...target = targetSource.getTarget();Class<?> targetClass = (target != null ? target.getClass() : null);List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);Object retVal;// Check whether we only have one InvokerInterceptor: that is,// no real advice, but just reflective invocation of the target.if (chain.isEmpty() && CglibMethodInvocation.isMethodProxyCompatible(method)) {// We can skip creating a MethodInvocation: just invoke the target directly.// Note that the final invoker must be an InvokerInterceptor, so we know// it does nothing but a reflective operation on the target, and no hot// swapping or fancy proxying.Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);retVal = invokeMethod(target, method, argsToUse, methodProxy);}else {// We need to create a method invocation...retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();}retVal = processReturnType(proxy, target, method, retVal);return retVal;// 省略...} }static boolean isMethodProxyCompatible(Method method) {return (Modifier.isPublic(method.getModifiers()) &&method.getDeclaringClass() != Object.class && !AopUtils.isEqualsMethod(method) &&!AopUtils.isHashCodeMethod(method) && !AopUtils.isToStringMethod(method)); }从注释也可以看出,当调用public方法时“just reflective invocation of the target“,即只是对目标的反射调用
相关文章:
SpringMVC控制层private方法中出现注入的service对象空指针异常
一、现象 SpringMVC中controller里的private接口中注入的service层的bean为null,而同一个controller中访问修饰符为public和protected的方法不会出现这样的问题。 controller中的方法被AOP进行了代理,普通Controller如果没有AOP,private方法…...
【Unity】P4 脚本文件(基础)
Unity脚本文件(基础)适配的C#代码编辑器如何添加一个脚本文件获取蘑菇当前位置基础代码改变物体位置帧与帧更新前言 上一篇博文主要围绕Unity Inspector部分,围绕组件,资源文件,父子节点部分做介绍。 链接:…...
(2023版)零基础入门网络安全/Web安全,收藏这一篇就够了
由于我之前写了不少网络安全技术相关的文章和回答,不少读者朋友知道我是从事网络安全相关的工作,于是经常有人私信问我: 我刚入门网络安全,该怎么学? 要学哪些东西? 有哪些方向? 怎么选&#x…...
Vue3电商项目实战-登录模块2【05-登录-表单校验、06-登录-消息提示组件封装、07-登录-账户登录、08-登录-手机号登录、09-退出登录】
文章目录05-登录-表单校验06-登录-消息提示组件封装07-登录-账户登录08-登录-手机号登录09-退出登录05-登录-表单校验 文档:https://vee-validate.logaretm.com/v4/ 支持vue3.0 第一步:安装 执行命令 npm i vee-validate4.0.3 第二步:导入 …...
Python 中都有哪些常见的错误和异常?
本文首发自「慕课网」,想了解更多IT干货内容,程序员圈内热闻,欢迎关注! 作者| 慕课网精英讲师 朱广蔚 Python 程序的执行过程中,当发生错误时会引起一个事件,该事件被称为异常。例如: 如果程…...
51单片机-1
1,单片机内部集成了CPU,RAM,ROM,定时器,中断系统,通讯接口等一系列电脑的常用硬件功能。单片机和计算机相比,单片机是一个袖珍版计算机 2,单片机里有中央处理器(CPU&…...
【Azure 架构师学习笔记】-Azure Data Factory (4)-触发器详解-事件触发器
本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Data Factory】系列。 接上文【Azure 架构师学习笔记】-Azure Data Factory (3)-触发器详解-翻转窗口 前言 事件触发指的是存储事件,所以在新版的ADF 中,已经明确了是“存储事件”,…...
【项目设计】高并发内存池(三)[CentralCache的实现]
🎇C学习历程:入门 博客主页:一起去看日落吗持续分享博主的C学习历程博主的能力有限,出现错误希望大家不吝赐教分享给大家一句我很喜欢的话: 也许你现在做的事情,暂时看不到成果,但不要忘记&…...
2023年,35岁测试工程师只能被“优化裁员”吗?肯定不是····
国内的互联网行业发展较快,所以造成了技术研发类员工工作强度比较大,同时技术的快速更新又需要员工不断的学习新的技术。因此淘汰率也比较高,超过35岁的基层研发类员工,往往因为家庭原因、身体原因,比较难以跟得上工作…...
gitlab部署使用,jenkins部署使用
gitlab部署使用,jenkins部署使用在线安装gitlab下载gitlab安装gitlab使用gitlab设置中文修改管理员密码创建组,创建项目,创建用户jenkins下载jenkins安装jenkin使用jenkins更改管理员密码配置拉取代码配置登录gitlab拉取代码的账号密码配置项目配置gitlab仓库配置构…...
从零开始的机械臂yolov5抓取gazebo仿真(环境搭建篇下)
sunday功能包使用介绍以及开源 sunday我给自己机械臂的命名,原型是innfos的gluon机械臂。通过sw模型文件转urdf。Sunday项目主要由六个功能包sunday_description、sunday_gazebo、sunday_moveit_config、yolov5_ros、vacuum_plugin、realsense_ros_gazebo组成&…...
GCC编译器 MinGW的下载安装使用教程
哎 总所周知 gcc可以用来编译C 和C。在linux广泛应用,那么window怎么使用gcc呢。就要用到gcc的window工具----MInGW,安装好之后,直接可以在windows的dos界面编译。下面讲解安装使用过程。1.官网下载MinGW - Minimalist GNU for Windows downl…...
【项目实战】SpringMVC配置全局属性,是实现WebMvcConfigurer接口,还是直接继承WebMvcConfigurationSupport类?
一、说明 官方推荐以下两种方式来配置全局的SpringMVC的相关属性 方式一:实现WebMvcConfigurer接口(推荐)方式二:直接继承WebMvcConfigurationSupport类。介绍一下两者区别吧。 二、 WebMvcConfigurer介绍 WebMvcConfigurer是一个接口,用于配置全局的SpringMVC的相关属…...
房产营销、地产中介如何高效低成本获客?
数字化对企业而言,机遇和挑战并存。房产企业可借助数字化加强日益扩大的业务规模和业务领域管理,以提升管理效率,降低管理难度;基于数字化技术加强客户的服务体验,进而收集多业态客户和场景数据,拓展创新业…...
Kotlin-作用域函数
在对象的上下文中执行代码块。当您在提供lambda表达式的对象上调用这样的函数时,它会形成一个临时作用域。在此范围内,可以不带名称地访问对象。这样的函数称为作用域函数。 let run with apply also 作用域函数不会引入任何新的技术功能,但它…...
QNX7.1 交叉编译开源库
1.下载QNX7.1 SDK并解压 ITL:~/work/tiqnx710$ ls -l 总用量 16 drwxrwxr-x 4 xxx4096 1月 28 13:38 host -rwxrwxr-x 1 xxx 972 1月 28 13:38 qnxsdp-env.bat -rwxrwxr-x 1 xxx 1676 1月 28 13:38 qnxsdp-env.sh drwxrwxr-x 3 xxx 4096 1月 28 13:38 target xxxITL:~/work/ti…...
论文投稿指南——中文核心期刊推荐(外国语言)
【前言】 🚀 想发论文怎么办?手把手教你论文如何投稿!那么,首先要搞懂投稿目标——论文期刊 🎄 在期刊论文的分布中,存在一种普遍现象:即对于某一特定的学科或专业来说,少数期刊所含…...
Fabric系列 - 链码-内部链码的特性
(1)Fabric repo下的案例 Chaincode(1.4的目录结构) fabric/examples/chaincode/go ├── example02 #一个简单的转账合约 ├── eventsender #发送事件通知 ├── passthru #调用其他链码(或者其他channel的链码)example02 (转账) 一个简单的转账合约。该链码简单实…...
NetApp SnapCenter 备份管理 ——借助应用程序一致的数据备份管理,简化混合云操作
NetApp SnapCenter 简单、可扩展、赋权:跨 Data Fabric 的企业级数据保护和克隆管理 主要优势 • 利用与应用程序集成的工作流和预定义策略简化备份、恢复和克隆管理。 • 借助基于存储的数据管理功能提高性能和可用性,并缩短测试和开发用时。 • 提供基…...
Java内置队列和高性能队列Disruptor
一、队列简介 队列是一种特殊的线性表,遵循先入先出、后入后出(FIFO)的基本原则,一般来说,它只允许在表的前端进行删除操作,而在表的后端进行插入操作,但是java的某些队列运行在任何地方插入删…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...
【Java学习笔记】BigInteger 和 BigDecimal 类
BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点:传参类型必须是类对象 一、BigInteger 1. 作用:适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
Unity UGUI Button事件流程
场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...
【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...
