Spring AOP对嵌套方法不起作用的解决

作者:波波仔86 时间:2022-01-08 16:55:03 

Spring AOP对嵌套方法不起作用

今天在调研系统操作记录日志时,好多教程都是借助于Spring AOP机制来实现。于是也采用这种方法来实现。在Service中的删除日志方法上注解自定义的切点,但是执行没有生效。

代码如下:

//尝试删除溢出日志
    public synchronized void tryDelOverflowLog() {
        logNum++;
        if (logNum - LogConst.MAX_NUM > 0) {
            int delNum = logNum - LogConst.MAX_NUM + LogConst.EXTRA_NUM;
            logNum -= delNum;
            removeOverflowLog(delNum);
        }
    }
 
    //日志溢出后,删除最新入库的日志
    @ServiceLog(type = LogConst.TYPE_LOG_RECORD, description = "操作日志缓存区溢出,系统自动清空缓存区")
    public void removeOverflowLog(int delNum) {
        custLogMapper.removeOverflowLog(delNum);
    }

在使用 Spring AOP 的时候,我们从 IOC 容器中获取的 Service Bean 对象其实都是代理对象,而不是那些 Service Bean 对象本身,也就是说获取的并不是被代理对象或代理目标。当我在自己的 Service 类中使用 this 关键字嵌套调用同类中的其他方法时,由于 this 关键字引用的并不是该 Service Bean 对象的代理对象,而是其本身,故 Spring AOP 是不能拦截到这些被嵌套调用的方法的。

要解决这个问题

最简单的方法是把自身注入到自身,用注入的这个自身去调用本方法。或者你也可以不用spring aop而是用aspectj weaving,倒是可以测底的解决该问题。我采用的是把自身注入到自身中。

    /**
     * 通过注入自身解决,Spring AOP嵌套调用不生效的问题
     */
    @Autowired
    private ApplicationContext applicationContext;
    private LogService self;
    @PostConstruct
    private void init() {
        self = (LogService) applicationContext.getBean("logService");
    }
   //尝试删除溢出日志
    public synchronized void tryDelOverflowLog() {
        logNum++;
        if (logNum - LogConst.MAX_NUM > 0) {
            int delNum = logNum - LogConst.MAX_NUM + LogConst.EXTRA_NUM;
            logNum -= delNum;
            self.removeOverflowLog(delNum);
        }
    }

Spring AOP、嵌套调用失效及解决

加入注解

@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)

获取当前代理的接口

public interface ICurrentAopProxyService<T> {
    default T getCurrentProxyService() {
        return (T) AopContext.currentProxy();
    }
}

需要嵌套调用的Service实现它

Spring AOP对嵌套方法不起作用的解决

调用的时候改写代码

public SysMerchantVersion selectByMerchantId(Long merchantId) {
       return getCurrentProxyService().getOne(new QueryWrapper<SysMerchantVersion>()
               .lambda()
               .eq(SysMerchantVersion::getMerchantId, merchantId));
   }

来源:https://blog.csdn.net/bobozai86/article/details/78896487

标签:Spring,AOP,嵌套方法
0
投稿

猜你喜欢

  • Java实现的上传并压缩图片功能【可等比例压缩或原尺寸压缩】

    2023-03-17 11:09:11
  • Java动态代理模式的深入揭秘

    2023-07-27 23:41:25
  • 在android中实现类似uc和墨迹天气的左右拖动效果

    2022-06-18 08:47:50
  • C#中label内容显示不全、不完整的解决方法

    2022-09-13 02:43:46
  • Mybatis 动态表名+Map参数传递+批量操作详解

    2023-04-02 04:08:00
  • 使用IntelliJ IDEA 配置安卓(Android)开发环境的教程详解(新手必看)

    2021-10-22 19:11:28
  • SpringBoot日志配置操作全面介绍

    2023-03-08 14:37:54
  • ssm框架下web项目,web.xml配置文件的作用(详解)

    2021-07-31 14:42:11
  • 在Winform程序中使用Spire.Pdf实现页面添加印章功能的实现

    2022-05-29 16:57:27
  • Java 实战项目锤炼之校园宿舍管理系统的实现流程

    2023-10-15 07:00:58
  • SpringBoot注册Servlet的三种方法详解

    2022-06-15 15:56:29
  • C#调用存储过程详解(带返回值、参数输入输出等)

    2023-12-06 01:06:35
  • Java去除字符串中空格的方法详解

    2022-10-16 23:42:13
  • Spring中事务传播行为的介绍

    2023-06-24 01:21:01
  • Java多线程实现Callable接口

    2022-09-01 17:53:54
  • SpringBoot 使用 FTP 操作文件的过程(删除、上传、下载文件)

    2021-07-26 10:40:05
  • C#简单的加密类实例

    2022-12-15 11:31:18
  • c# 调用Surfer软件,添加引用的具体操作方法

    2023-12-06 17:05:37
  • Java编程实现对象克隆(复制)代码详解

    2023-02-13 10:12:31
  • android gradle如何修改生成的apk名字

    2023-03-09 23:38:56
  • asp之家 软件编程 m.aspxhome.com