SpringBoot项目中注解使用规范

1.springboot AOP默认使用cglib代理

aop为何一直使用cglib代理的原因:

spring boot项目启动类上有一@SpringBootApplication注解,这是一套组合注解:注解内部的定义,找到@EnableAutoConfiguration,再找到@Import(AutoConfigurationImportSelector.class)

AutoConfigurationImportSelector类的process方法,AopAutoConfiguration类的主要任务是根据配置参数使用注解@EnableAspectJAutoProxy

而:该类启用的条件是:配置参数spring.aop.auto值不为false,我们的spring-configuration-metadata.json中有配置:当spring.aop.proxy-target-class缺省配置时默认也是true,spring-boot里面默认就是true,所以默认使用aop的cglib代理。

2.为什么springBoot中,注解在私有方法上,或者内部调用的方法上,无法生效原因解析

  1. 注解是借助Spring AOP实现

  2. spring aop默认都是采用java的动态代理,其次才会使用cglib代理

为什么不能在私有方法上注解:

如果从aop的角度去分析,那么答案就是:因为cglib

原因:cglib实现动态代理,其底层采用了ASM字节码生成框架,直接对需要代理的类的字节码进行操作,生成这个类的一个子类,并重写了类的所有可以重写的方法。

由于cglib的代理类使用的是继承,这也就意味着cglib不能代理final类,同时也不能对private方法进行代理!子类无法重写private方法!

aop不支持对private私有方法的拦截,所以也就不支持私有方法上的注解

为什么 类内部方法调用不支持 , 如果是类内部方法调用,为什么就不能生效?

注解了的类是被cglib重新增强代理过的类。类内部方法互调,相当于this.function()的调用模式,这里的this是类本身,并不是被代理的类,所以不走代理,注解不生效。

综上所述 :springboot默认使用cglib代码,cglib为类生成子类,进行增强,所以不会重写父类的private的类,所以注解在私有方法上不生效。其次,类内部的方法调用,用的是this.function()的形式,其中this是类本身,不是被代理的类,所以类内部方法调用,注解不会生效。

3.注解在CGLIB代理中的表现

  1. 注解的位置:注解可以放在目标类的各个方法上,包括 public、protected、default 和 private 方法。

  2. 代理机制的影响:

  • 公共方法 (public):这些方法可以通过代理对象正常访问,并且注解也会被正确识别和处理。
  • 非公共方法 (protected, default, private):这些方法只能通过原生对象访问,而不是通过代理对象。因此,如果在这些方法上调用了带有注解的操作(如事务管理、异步执行等),注解的效果可能会受到影响。

4.解决方案

  1. 重构方法结构:将需要特殊处理的方法移到一个新的类中,并使其成为 public 或 protected 方法。
  2. 使用AopContext获取代理对象:如果必须保持单一类的设计,可以使用 AopContext.currentProxy() 获取当前代理对象,然后通过该代理对象调用方法。

总结:

  • 注解可以放置在类内部的各种方法上,包括 private 方法。

  • CGLIB代理会影响非公共方法的注解解析,只有通过代理对象调用的方法才能正确响应注解。

  • 建议将需要特殊处理的方法提取到新的类中,或者使用 AopContext.currentProxy() 获取代理对象来确保注解的有效性。

推荐阅读:

https://zhuanlan.zhihu.com/p/452611889

相关推荐
小码哥_常1 小时前
一套自己部署的 IM,客户端是同一份 Flutter
前端·后端
学长毕设4 小时前
基于SpringBoot的实验室资产管理系统
java·spring boot·后端
zzu123zsw5 小时前
从臃肿的模板调用到声明式契约:深入 UniHttp 动态代理与多渠道生命周期扩展
java·spring boot·microsoft·unihttp
源码集结号6 小时前
云诊所门诊系统源码,基于SpringBoot+Vue.js架构,支持多租户设计与Docker容器化部署
java·spring boot·源码·医院信息系统·门诊系统·诊所系统
努力的小雨6 小时前
给 AI 眼镜开发应用有多难?我从零做了一个陪练,还上架了
后端
论文复现现场6 小时前
WRF、FEA 能用 L40S 加速吗?求解器检查、断点恢复与长期运行
java·数据库·算法·wrf·有限元分析·gpu计算·断点续算
啃瓜子的松鼠6 小时前
泛微OAe9-后端二开异步调用
java
秋天的怀念_David7 小时前
第二十一夜 · 数字黑洞与西西弗斯的惩罚
java·程序人生·算法
excel7 小时前
双 Token 与前端使用 Crypto 公私钥鉴权换 Token,哪种方案更好?
前端·后端
外收内放7 小时前
Python基础语法练习题(73)
java·前端·python