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

目录
  • Spring AOP对嵌套方法不起作用
    • 要解决这个问题
  • Spring AOP、嵌套调用失效及解决
    • 加入注解
    • 获取当前代理的接口
    • 需要嵌套调用的Service实现它
    • 调用的时候改写代码

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实现它

调用的时候改写代码

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

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • spring使用aspect注解切面不起作用的排查过程及解决

    今天做spring使用aspect注解demo,发现不起作用,问题排查如下: 1.程序正常启动,说明jar包依赖没有问题 2.debug程序不进入切面,有可能是路径问题,根据这个思路,果真是路径问题,在切面配置类的使用@ComponentScan的路径写错了. 扫描的路径为:注解类.切面类及service的上一层目录即可,假设项目的结构如下: 则@ComponenScan("demo.com.nrt")即可 SpringBoot切面@aspect--- 注解在嵌套方法不生效的问题 例如

  • SpringBoot使用AOP,内部方法失效的解决方案

    目录 SpringBoot使用AOP,内部方法失效 AOP切面 现在有两个方法 写一个简单的动态代理的例子 SpringBoot使用AOP,内部方法失效 最近在使用AOP的时候,发现一个问题,普通的方法AOP就能够有用,而内部调用的方法AOP就会失效,下面重现下问题 AOP切面 @Aspect @Component public class AuthorityAspect { @Pointcut("execution(* authority.service.AuthorityService.ge

  • 解决springboot的aop切面不起作用问题(失效的排查)

    检查下springboot的启动类是否开启扫描 @SpringBootApplication @ComponentScan(basePackages = {"com.zhangpu.springboot"}) 另外springboot默认开启的EnableAspectJAutoProxy为true 如果不放心可以增加: @EnableAspectJAutoProxy(proxyTargetClass=true) 第二种可能: 没有导入 相关的jar <dependency>

  • 详解spring中aop不生效的几种解决办法

    先看下这个问题的背景:假设有一个spring应用,开发人员希望自定义一个注解@Log,可以加到指定的方法上,实现自动记录日志(入参.出参.响应耗时这些) package com.cnblogs.yjmyzz.springbootdemo.aspect; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy

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

    目录 Spring AOP对嵌套方法不起作用 要解决这个问题 Spring AOP.嵌套调用失效及解决 加入注解 获取当前代理的接口 需要嵌套调用的Service实现它 调用的时候改写代码 Spring AOP对嵌套方法不起作用 今天在调研系统操作记录日志时,好多教程都是借助于Spring AOP机制来实现.于是也采用这种方法来实现.在Service中的删除日志方法上注解自定义的切点,但是执行没有生效. 代码如下: //尝试删除溢出日志     public synchronized void

  • Spring AOP 对象内部方法间的嵌套调用方式

    目录 Spring AOP 对象内部方法间的嵌套调用 我们先定义一个接口 以及此接口的一个实现类 增加AOP处理 同一对象内的嵌套方法调用AOP失效原因分析 举一个同一对象内的嵌套方法调用拦截失效的例子 原因分析 解决方案 Spring AOP 对象内部方法间的嵌套调用 前两天面试的时候,面试官问了一个问题,大概意思就是一个类有两个成员方法 A 和 B,两者都加了事务处理注解,定义了事务传播级别为 REQUIRE_NEW,问 A 方法内部直接调用 B 方法时能否触发事务处理机制. 答案有点复杂,

  • Spring AOP访问目标方法的参数操作示例

    本文实例讲述了Spring AOP访问目标方法的参数操作.分享给大家供大家参考,具体如下: 一 配置 <?xml version="1.0" encoding="GBK"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns

  • 解决spring AOP中自身方法调用无法应用代理的问题

    目录 spring AOP中自身方法调用无法应用代理 如下例 可以使用如下两种方式修改代码以应用事务 (1)在MyServiceImpl中声明一个MyService对象 (2)使用AopContext类 spring aop 内部方法调用事务不生效 方法1: 方法2: spring AOP中自身方法调用无法应用代理 如下例 public class MyServiceImpl implements MyService { public void do(){ //the transaction a

  • spring aop 拦截业务方法,实现权限控制示例

    难点:aop类是普通的java类,session是无法注入的,那么在有状态的系统中如何获取用户相关信息呢,session是必经之路啊,获取session就变的很重要.思索很久没有办法,后来在网上看到了解决办法. 思路是: i. SysContext  成员变量 request,session,response ii. Filter 目的是给 SysContext 中的成员赋值 iii.然后在AOP中使用这个SysContext的值 要用好,需要理解  ThreadLocal和  和Filter

  • Aspectj与Spring AOP的对比分析

    1.简介 今天有多个可用的 AOP 库, 它们需要能够回答许多问题: 1.是否与用户现有的或新的应用程序兼容? 2.在哪里可以实现 AOP? 3.与自己的应用程序集成多快? 4.性能开销是多少? 在本文中, 我们将研究如何回答这些问题, 并介绍 Spring aop 和 AspectJ, 这是 Java 的两个最受欢迎的 aop 框架. 2.AOP概念 在开始之前, 让我们对术语和核心概念进行快速.高层次的审查: Aspect -- 一种标准代码/功能, 分散在应用程序中的多个位置, 通常与实际

  • Spring AOP面向切面编程实现原理方法详解

    1. 什么是AOP AOP (Aspect Oriented Programming)意为:面向切面编程,通过预编译方式和运行期动态代理实现在不修改源代码的情况下,给程序动态统一添加功能的一种技术,可以理解成动态代理.是Spring框架中的一个重要内容.利用 AOP 可以对业务逻辑的各个部分进行隔离,使业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高开发的效率 2. Spring AOP ①. AOP 在Spring中的作用 提供声明式事务:允许用户自定义切面 ②. AOP 的基本概

  • 图解JAVA中Spring Aop作用

    假如没有aop,在做日志处理的时候,我们会在每个方法中添加日志处理,比如 但大多数的日子处理代码是相同的,为了实现代码复用,我们可能把日志处理抽离成一个新的方法.但是这样我们仍然必须手动插入这些方法. 但这样两个方法就是强耦合的,假如此时我们不需要这个功能了,或者想换成其他功能,那么就必须一个个修改. 通过动态代理,可以在指定位置执行对应流程.这样就可以将一些横向的功能抽离出来形成一个独立的模块,然后在指定位置 插入这些功能.这样的思想,被称为面向切面编程,亦即AOP. 为了在指定位置执行这些横

  • 利用Spring AOP记录方法的执行时间

    一.前言 对于spring aop这个我就不多介绍了,网上一搜一大把,使用过spring的人都知道spring的ioc和aop.ioc我们常用,但在我们自己的系统中,aop的使用几乎为零,除了这个监控的小功能应用到了,其他的基本上没有使用到.下面小编就给大家整理下利用Spring AOP记录方法执行时间的解决方案,有需要的一起看看吧. 二.解决方案 1.传统方法 最简单.粗暴的方法是给各个需要统计的方法开始和结尾处加的时间戳,然后差值计算结果即可,代码如下: long startTime = S

  • Spring Aop之AspectJ注解配置实现日志管理的方法

    最近项目要做一个日志功能,我用Spring Aop的注解方式来实现. 创建日志注解 package com.wyj.annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lan

随机推荐