花了 2 个钟才搞懂这 AOP 为啥没生效,水友却睡着了……
lipiwang 2024-11-13 13:39 32 浏览 0 评论
Springboot中 AOP失效的原因
今天 4ye 来和小伙伴们分享一个小实战啦 ,冲冲冲~ (。???)ノ
实战回顾
(我居然拖到现在才写了这文章…… )
主要是在一个周日(2021.6.6)在技术群里看到一个老哥在问
“怎么用切面来捕获自定义异常?” ( ̄▽ ̄)"
我当时想的是,捕获异常不是很常见的吗,平时经常用到这个全局异常捕获 ,于是就把自己 GitHub 上的小例子发给他(主要是这个 ControllerAdvice 注解),如图
结果老哥过了一段时候就加了我,还问我有没有空帮忙看下,还想打电话问我,我当时的内心是
这么急的吗(瑟瑟发抖……)
不过刚好在外面没时间,就婉拒了,后来晚上回来,愣是花了两个钟,才看懂 为啥这个AOP 没有生效?为啥没能捕获到异常?
下面进入主题(项目整体介绍)
maven项目结构图
在该项目中,maven项目采用多模块构建,父子结构,由 父maven 来统一管理这些公共包,以及项目的整体版本属性配置等
里面有两个模块,starter 模块和 core 模块,其中 starter 模块依赖 core 模块,整体如下图
子模块介绍
不知道小伙伴们看到上面的 starter 有没有嗅到什么 ?
一开始我以为是常见的 自定义starter ,但是里面的内容却和我想的有点出入,居然只有一个 spring.factories 文件, 很明显这里使用到了 Springboot 的 SPI 机制。
这个在我们之前的 Springboot自动装配原理探索 一文中有介绍到,小伙伴们可以前去了解看看~
对两个模块中的核心部分进行展开,结构如下
core项目描述:非web项目里面只有 service ,没有启动类等
由于 core 模块 不是web项目!!,所以这个 ControllerAdvice 是肯定不能用的,毕竟它是在 web 包中的,一般我们在 web项目中配合这个@ExceptionHandler(Exception.class) 实现全局异常捕获,然后进行统一处理的。
从 Springboot 的 SPI 机制 中我们可以得知,Springboot 项目启动时,会去扫描各个项目中的 META-INF/spring.factories 文件(包括各个jar包),然后将其中的配置信息读取到内存中,而自动配置时会根据一定的条件对这些类进行筛选,最后创建符合的类,完成这个自动装配。
很明显,这里就是通过自动配置,来实现相关 bean 的注入。
配置类说明
那么,在了解了这些基本信息后,我们可以把目光移到这个 xxxConfig 上,这里模仿了一个
紧接着就是项目中的切面配置了,例如以前写的小例子:
代码在我的 GitHub :
https://github.com/RyzeYang/springboot-demo-4ye.git
通过异常通知来捕获
除了上面这两个之外,项目中没有用到其他配置了!
问题来了
这个时候问题就来了,在定义了切面之后,发现根本没有在项目中起作用!而其他都可以正常运行!
于是我一直在想,这是为啥呀,明明切面已经定义好了呀……
终于,我开始了尝试,在 yaml 配置文件中添加这个参数
spring:
aop:
auto: true
因为在印象中,这个默认是 true ,会默认使用这个 @EnableAspectJAutoProxy , 不用我们手动去添加这个 @EnableAspectJAutoProxy 注解(之前一直没有手动添加这个注解)
结果也没什么效果……
于是乎,我决定手动添加到刚刚那个 xxxConfig 配置类上,结果也没有什么作用……
终于,我才想起那个 切面配置 没有被加载到这个 Spring 中 ,于是我又在那个配置类 xxxConfig 上添加了这个包扫描注解 @ComponentScan(basePackages = "com.xxx.xxx")
结果终于成功了!
于是我赶在 23:59 将修改后的文件发给那位老哥后,却发现他居然睡着了 哈哈哈
问题剖析
解决问题后,我们可以发现这个问题就下面两点
- 没有将切面注册到 SpringIOC 容器中
- 没有使用这个 @EnableAspectJAutoProxy
第一步的解决也很简单,就是没有配置这个包扫描 @ComponentScan(basePackages = "com.xxx.xxx")
第二步的解决嘛,就有点一头雾水了当时,毕竟之前也不需要我手动去添加的,而且从配置的描述信息中可以发现,即使我们没有配置,他也是默认开启的,会自动使用这个注解的~
那么小伙伴们知道第二步问题的所在吗
嘿嘿,答案就出在这个自动配置 身上,可以发现我们上面都没有使用到这个 @EnableAutoConfiguration 注解,而在我们的 SpringBootApplication 组合注解中,最重要的就是它了! 通过它去开启了我们的这个自动装配。
这个时候又得把这文章搬出来了 Springboot自动装配原理探索 哈哈
那么我们再来看看这个 AOP自动装配的配置类
AOP自动装配的配置类
AopAutoConfiguration 源码如下
开头有这么一个条件注解
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
havingValue = "true" 的意思是:值为 true 时才有效
matchIfMissing = true 的意思是:没有配置这个属性时也能加载
接着让我们把目光移到第一个静态内部类: AspectJAutoProxyingConfiguration
如图:
这个我们也比较熟悉啦, proxyTargetClass 为 true 时表示使用 cglib ,false 使用 JDK动态代理
接着看最后的静态内部类: ClassProxyingConfiguration
可以发现它这里的条件是和 AspectJAutoProxyingConfiguration 相反的,当没有这个 Advice 类时,帮我们去注册这个代理到 IOC 中
看完该AOP自动装配类后, 我们可以发现当我们使用 @EnableAutoConfiguration 自动装配注解时并引入 AOP 的包时,它会自动帮我们装配这个AopAutoConfiguration ,而它里面就使用到了 @EnableAspectJAutoProxy ,所以我们一般不用手动添加该注解。
怎么测试
嘿嘿,再出一个小问题考考小伙伴
有没有细心的小伙伴发现上面的 core 模块是没有用到这个 SpringBootApplication 的,而且我们也没有用到这个 @EnableAutoConfiguration ,那么没有自动装配,这个 SPI 显然也没啥作用 ,那么,我们在项目中要怎么测试呢~
答案就在 单元测试的注解身上 @SpringBootTest(classes = xxxConfiguration.class)
通过这个 classes ,我们直接指定并实例化这个配置类就可以了
我也是报错了才知道 哈哈
总结
嘿嘿,老规矩,画个图总结下啦
排查思路
知识脑图
那么,本期就分享到这啦,喜欢的小伙伴记得点点赞呀~ 下期看看情况分享下下面某一个叭
- Springboot自定义starter
- 利用AOP实现插件
- Spring源码
最后
欢迎小伙伴们来一起探讨问题~
如果你觉得本篇文章还不错的话,那拜托再点点赞支持一下呀
让我们开始这一场意外的相遇吧!~
欢迎留言!谢谢支持!ヾ(≧▽≦*)o 冲冲冲!!
我是4ye 咱们下期应该……很快再见!!
喜欢的话可以关注下 头条号 和 公众号 Java4ye 支持下 4ye 呀
相关推荐
- 前端入门——css 网格轨道详细介绍
-
上篇前端入门——cssGrid网格基础知识整体大概介绍了cssgrid的基本概念及使用方法,本文将介绍创建网格容器时会发生什么?以及在网格容器上使用行、列属性如何定位元素。在本文中,将介绍:...
- Islands Architecture(孤岛架构)在携程新版首页的实践
-
一、项目背景2022,携程PC版首页终于迎来了首次改版,完成了用户体验与技术栈的全面升级。作为与用户连接的重要入口,旧版PC首页已经陪伴携程走过了22年,承担着重要使命的同时,也遇到了很多问题:维护/...
- HTML中script标签中的那些属性
-
HTML中的<script>标签详解在HTML中,<script>标签用于包含或引用JavaScript代码,是前端开发中不可或缺的一部分。通过合理使用<scrip...
- CSS 中各种居中你真的玩明白了么
-
页面布局中最常见的需求就是元素或者文字居中了,但是根据场景的不同,居中也有简单到复杂各种不同的实现方式,本篇就带大家一起了解下,各种场景下,该如何使用CSS实现居中前言页面布局中最常见的需求就是元...
- CSS样式更改——列表、表格和轮廓
-
上篇文章主要介绍了CSS样式更改篇中的字体设置Font&边框Border设置,这篇文章分享列表、表格和轮廓,一起来看看吧。1.列表List1).列表的类型<ulstyle='list-...
- 一文吃透 CSS Flex 布局
-
原文链接:一文吃透CSSFlex布局教学游戏这里有两个小游戏,可用来练习flex布局。塔防游戏送小青蛙回家Flexbox概述Flexbox布局也叫Flex布局,弹性盒子布局。它决定了...
- css实现多行文本的展开收起
-
背景在我们写需求时可能会遇到类似于这样的多行文本展开与收起的场景:那么,如何通过纯css实现这样的效果呢?实现的难点(1)位于多行文本右下角的展开收起按钮。(2)展开和收起两种状态的切换。(3)文本...
- css 垂直居中的几种实现方式
-
前言设计是带有主观色彩的,同样网页设计中的css一样让人摸不头脑。网上列举的实现方式一大把,或许在这里你都看到过,但既然来到这里我希望这篇能让你看有所收获,毕竟这也是前端面试的基础。实现方式备注:...
- WordPress固定链接设置
-
WordPress设置里的最后一项就是固定链接设置,固定链接设置是决定WordPress文章及静态页面URL的重要步骤,从站点的SEO角度来讲也是。固定链接设置决定网站URL,当页面数少的时候,可以一...
- 面试发愁!吃透 20 道 CSS 核心题,大厂 Offer 轻松拿
-
前端小伙伴们,是不是一想到面试里的CSS布局题就发愁?写代码时布局总是对不齐,面试官追问兼容性就卡壳,想跳槽却总被“多列等高”“响应式布局”这些问题难住——别担心!从今天起,咱们每天拆解一...
- 3种CSS清除浮动的方法
-
今天这篇文章给大家介绍3种CSS清除浮动的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。首先,这里就不讲为什么我们要清楚浮动,反正不清除浮动事多多。下面我就讲3种常用清除浮动的...
- 2025 年 CSS 终于要支持强大的自定义函数了?
-
大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!1.什么是CSS自定义属性CSS自...
- css3属性(transform)的一个css3动画小应用
-
闲言碎语不多讲,咱们说说css3的transform属性:先上效果:效果说明:当鼠标移到a标签的时候,从右上角滑出二维码。实现方法:HTML代码如下:需要说明的一点是,a链接的跳转需要用javasc...
- CSS基础知识(七)CSS背景
-
一、CSS背景属性1.背景颜色(background-color)属性值:transparent(透明的)或color(颜色)2.背景图片(background-image)属性值:none(没有)...
- CSS 水平居中方式二
-
<divid="parent"><!--定义子级元素--><divid="child">居中布局</div>...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- maven镜像 (69)
- undefined reference to (60)
- zip格式 (63)
- oracle over (62)
- date_format函数用法 (67)
- 在线代理服务器 (60)
- shell 字符串比较 (74)
- x509证书 (61)
- localhost (65)
- java.awt.headless (66)
- syn_sent (64)
- settings.xml (59)
- 弹出窗口 (56)
- applicationcontextaware (72)
- my.cnf (73)
- httpsession (62)
- pkcs7 (62)
- session cookie (63)
- java 生成uuid (58)
- could not initialize class (58)
- beanpropertyrowmapper (58)
- word空格下划线不显示 (73)
- jar文件 (60)
- jsp内置对象 (58)
- makefile编写规则 (58)