springboot 使用注解,对注解使用切面后,Controller调用service一直报null的问题解决。

百度后的答案是:

springboot 注解加切面 后controller, service为null
报错问题:“springboot 注解加切面后controller, servise为null” 通常意味着在使用Spring Boot时,通过注解定义的切面成功创建了,但是与之相关联的Controller或Service组件没有被Spring容器正确注入。

可能的原因和解决方法:

组件扫描问题:确保Controller和Service类所在的包在Spring Boot应用的@SpringBootApplication注解或@ComponentScan注解的扫描路径之内。

切面优先级问题:如果使用了AspectJ来创建切面,并且切面的优先级设置不当,可能会导致在切面执行之后,Controller和Service还没有完成依赖注入。可以通过提升切面的优先级来解决这个问题。

切面实现问题:检查切面的实现代码,确保没有在切面中直接通过new关键字来创建Controller或Service的实例,这样会导致Spring容器控制的实例化过程被绕开,从而引发空指针异常。

代理模式问题:Spring AOP默认使用的是代理模式,如果在Service或Controller中直接调用了自己的方法,可能导致此时的调用并没有被AOP代理拦截,因此没有经过切面处理的方法内部调用会导致注入的bean为null。

配置问题:检查Spring Boot的配置文件,确保没有错误配置导致组件创建或注入失败。

版本兼容问题:确保Spring Boot的版本和其他Spring组件的版本之间是兼容的,有时候版本不匹配也会导致组件无法正常注入。

解决方法通常涉及检查和调整配置,确保Spring的组件扫描路径正确,切面优先级设置适当,并且避免在不适当的上下文中直接实例化Bean。如果问题依然存在,可以通过增加日志输出或使用调试工具来进一步诊断问题。

使用上述方法后仍然存在问题。
修改切面页面注解 @Aspect为@EnableAspectJAutoProxy后问题解决。
但是在切面上加@EnableAspectJAutoProxy虽然可以解决service调用时为null的问题,但是切面不起作用了。查阅资料后@EnableAspectJAutoProxy应该加在配置管理的代码中,也就是扫描包的文件。在切面文件中加@Aspect后,切面才可以起作用,最后查找原因,原来是使用切面的页面Controller上有方法上调用了final关键字,需要把所有的方法上的final都去掉,调用的方法才不会报null,同时需要注意的是方法不能是private类型
切面页面如下 LimitAspect.java

package com.turingoal.tms.config;
import com.google.common.collect.Maps;
import com.google.common.util.concurrent.RateLimiter;
import com.turingoal.common.exception.TgException;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.Map;@Slf4j
@Aspect 
@Component
public class LimitAspect {private final Map<String, RateLimiter> limitMap = Maps.newConcurrentMap();@Around("@annotation(Limit)")public Object around(ProceedingJoinPoint pjp) throws Throwable {MethodSignature signature = (MethodSignature)pjp.getSignature();Method method = signature.getMethod();//拿limit的注解Limit limit = method.getAnnotation(Limit.class);if (limit != null) {//key作用:不同的接口,不同的流量控制String key=limit.key();RateLimiter rateLimiter;//验证缓存是否有命中keyif (!limitMap.containsKey(key)) {// 创建令牌桶rateLimiter = RateLimiter.create(limit.permitsPerSecond(),limit.timeout(),limit.timeunit());limitMap.put(key, rateLimiter);log.info("新建了令牌桶={},容量={}",key,limit.permitsPerSecond());}rateLimiter = limitMap.get(key);// 拿令牌boolean acquire = rateLimiter.tryAcquire();// 拿不到命令,直接返回异常提示if (!acquire) {log.debug("令牌桶={},获取令牌失败",key);throw new TgException(limit.msg());}}return pjp.proceed();}}

注解Limit

package com.turingoal.tms.config;
import org.junit.jupiter.api.Order;import java.lang.annotation.*;
import java.util.concurrent.TimeUnit;@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Order(1)
public @interface Limit {// 资源keyString key() default "";// 最多访问次数int permitsPerSecond();// 时间long timeout();// 时间类型TimeUnit timeunit() default TimeUnit.MILLISECONDS;// 提示信息String msg() default "系统繁忙,请稍后再试";}

controller调用的方法:切记返回的方法上不能加final

  	@Limit(key = "findToolItems", permitsPerSecond = 1, timeout = 1000, msg = "当前查询较频繁,请稍后再试!")@RequestMapping(value = "/findToolItems.gsp", method = { RequestMethod.GET, RequestMethod.POST })@Operation(tags = {"XXX"}, summary = "查询[XXX]", description = "通过条件查询[XXX项]")public ResponseBean findItems(final ToolItemQuery query) throws TgException {query.setIsWorkwear(2);Page<Entity> data = service.findItems(query);return ResponseBean.page(data);}

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

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

相关文章

实现keepalive+Haproxyde 的高可用

需要准备五台实验机 一台客户机&#xff1a;test1 两台&#xff1a;一主一备的实验机&#xff1a;test2 test3 两台真实服务器&#xff1a;nginx1 nginx2 实验 首先在两台实验机上安装Haproxy 安装依赖环境&#xff0c;并将Haproxy的包进行解压处理 yum install -y pcre…

nodejs安装部署运行vue前端项目

文章目录 1.安装nodejs2.安装Vue CLI1.配置npm镜像源&#xff1a;2.安装Vue CLI&#xff1a;3.创建Vue项目4.启动Vue项目5.Express 1.安装nodejs Node.js 是一个免费、开源、跨平台的 JavaScript 运行时环境&#xff0c;它让开发人员能够创建服务器、Web 应用、命令行工具和脚…

【自动驾驶汽车通讯协议】UART通信详解:理解串行数据传输的基石

文章目录 0. 前言1. 同步通讯与异步通讯1.1 同步通信1.2 异步通信 2. UART的数据格式3. 工作原理3.1 波特率和比特率3.2 UART的关键特性 4. UART在自动驾驶汽车中的典型应用4.1 UART特性4.2应用示例 5. 结语 0. 前言 按照国际惯例&#xff0c;首先声明&#xff1a;本文只是我自…

MFC:文本可视化输出

文章目录 1. DrawText&#xff1a;2. TextOut&#xff1a;3. SetTextColor&#xff1a;4. SetBkColor&#xff1a;5. GetTextMetrics&#xff1a; 在MFC&#xff08;Microsoft Foundation Classes&#xff09;中&#xff0c;CDC&#xff08;设备上下文类&#xff09;提供了多种…

Barabási–Albert模型详解与Python代码示例

Barabsi–Albert模型详解与Python代码示例 模型介绍 Barabsi–Albert&#xff08;BA&#xff09;模型是一种用于模拟和分析复杂网络结构的数学模型&#xff0c;特别适用于描述那些具有“无标度”特性的网络。无标度网络是指网络中节点的连接度&#xff08;度&#xff09;分布…

xlive.dll丢失怎么办,xlive.dll文件的主要用途

xlive.dll丢失怎么办&#xff1f;目前是有很多方法可以解决这个xlive.dll丢失的问题的&#xff0c;只要你仔细的去了解xlive.dll这个文件&#xff0c;至于使用哪种方法&#xff0c;主要还是看你的实际情况&#xff0c;因为情况不同选择使用的方法也是不一样的&#xff0c;下面一…

底软驱动 | Linux虚拟内存

为了更有效的管理内存并且少出错&#xff0c;现代操作系统提供了一种对主存的抽象概念&#xff0c;叫做虚拟内存(VM)。虚拟内存提供了三个重要的能力: 1.它将主存(物理内存)看成是一个存储在磁盘上的地址空间的高速缓存&#xff0c;在主存中只保留活动区域&#xff0c;并且根据…

去除重复数字

1083. 【基础】去除重复数字 [ 刷题2路4线 ] 时间限制: 1000MS 空间限制: 16MB 结果评判: 文本对比 正确/提交: 29 (21) / 45 官方标签: 数组 普及- 题目描述 给你N个数&#xff08;n&#xff1c;&#xff1d;&#xff11;&#xff10;&#xff10;&#xff09;,每个数都在&am…

openEuler 安装 podman 和 podman compose

在 openEuler 22.03 LTS SP4 中&#xff0c;你可以使用 dnf 包管理器来安装 Podman 和 Podman Compose。openEuler 默认使用 dnf 作为包管理器&#xff0c;所以这是安装软件的首选方式。 关于 openEuler 22.03 LTS SP4 下载地址&#xff1a; https://www.openeuler.org/zh/dow…

【256 Days】我的创作纪念日

目录 &#x1f33c;01 机缘 &#x1f33c;02 收获 &#x1f33c;03 日常 &#x1f33c;04 成就 &#x1f33c;05 憧憬 最近收到官方来信&#xff0c; 突然发现&#xff0c;不知不觉间&#xff0c;距离发布的第一篇博客已过256天&#xff0c;这期间我经历了春秋招、毕业答辩…

JS【详解】ES6 模块规范 vs CommonJS 模块规范

每个 js 文件都是一个模块&#xff0c;默认采用的 CommonJS 模块规范 新兴的 ES6 模块 pk 传统的 CommonJS 模块 特性CommonJSES6 模块化导出exports 对象export 关键字导入require()函数import 关键字加载模式同步异步执行模式单例单例依赖关系静态动态树形摇晃不支持支持 加…

板级调试小助手(3)基于PYNQ的OLED视频显示

一、前言 在之前的文章中介绍了《板级调试小助手》的系统结构和DDS自定义外设的搭建。这篇文章主要介绍一下如何在PYNQ中驱动平时长剑的OLED12864显示屏&#xff0c;并显示BadApple&#xff08;毕竟有屏幕的地方就要有BadApple&#xff09;。效果如下&#xff1a; BadApple 本项…

Access denied for user ‘root‘@‘localhost‘ (using password: YES)解决办法

在Spring配置数据源时&#xff0c;当使用Spring容器加载druid.properties数据库连接池配置文件时&#xff0c;容易碰到create connection SQLException, url: jdbc:mysql://127.0.0.1:3306/mydbs, errorCode 1045, state 28000 java.sql.SQLException: Access denied for user …

破解YouTube限制:保姆级教程,轻松查看博主邮箱

近期YouTube取消了博主的邮箱展示&#xff0c;这造成了不小的轰动&#xff0c;给想要联系博主的粉丝和想要寻求网红合作的品牌都带来了极大的不便。但这难不倒万能的网友&#xff01;最新发现&#xff0c;通过一串神秘代码可以在YouTube上查看到博主的邮箱&#xff0c;这里Nox聚…

Java进阶----多态

多态 什么是多态 在继承父类或者实现接口的基础上&#xff0c;允许同一类事物出现不同的状态 多态的前提&#xff1a;继承或实现的关系、方法的重写、父类&#xff08;接口&#xff09;引用指向子类&#xff08;实现类&#xff09;对象 表现形式 父类 变量 子类对象(); 接…

解决方案架构师系列 - AWS - AWS Amplify 服务功能介绍

探索AWS Amplify&#xff1a;构建高效、安全的云原生应用 AWS Amplify 是一个开源框架&#xff0c;由亚马逊网络服务&#xff08;AWS&#xff09;提供&#xff0c;旨在简化Web和移动应用程序的开发。它是一套完整的开发工具集合&#xff0c;帮助开发者快速地实现功能如身份验证…

CycleGAN深度学习项目

远程仓库 leftthomas/CycleGAN: A PyTorch implementation of CycleGAN based on ICCV 2017 paper "Unpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks" (github.com) 运行准备 Anaconda 安装需要的库 指令 pip install panda…

LPRNet 车牌识别部署 rk3588(pt-onnx-rknn)包含各个步骤完整代码

虽然车牌识别技术很成熟了&#xff0c;但完全没有接触过。一直想搞一下、整一下、试一下、折腾一下&#xff0c;工作之余找了一个简单的例子入个门。本博客简单记录一下 LPRNet 车牌识别部署 rk3588流程&#xff0c;训练参考 LPRNet 官方代码。 1、导出onnx   导出onnx很容易…

昇思25天打卡营-mindspore-ML- Day24-基于 MindSpore 实现 BERT 对话情绪识别

学习笔记&#xff1a;基于MindSpore实现BERT对话情绪识别 算法原理 BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;是由Google于2018年开发的一种预训练语言表示模型。BERT的核心原理是通过在大量文本上预训练深度双向表示&#xff0…

Win7电脑修改网卡配置连接千兆网络的方法

Win7电脑修改网卡配置连接千兆网络的方法 Realtek PCIe GBE Family Controller是千兆网卡,GBE的意思就是1Gbps网卡,也就是千兆网卡,翻译成中文就是瑞昱PCI-E总线千兆网络系列控制器。 目前有很多的电脑都是使用realtek网卡的,当时奇怪的是网卡连接到h3或者d-link千兆交换机…