Spring AOP类中方法调用自身其他方法的解决方案

本文介绍了一种解决Spring AOP中同一类内方法调用导致AOP失效的问题的方法,通过使用Aops工具类获取代理对象进行方法调用,确保了AOP的正常工作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

由来

例如这个类:

@Repository
public class ErpRemarkRecordDao extends BaseDao<ErpRemarkRecord> {

    @Override
    protected String getTableName() {
        return "erp_remark_record";
    }

    /** 获得最新沟通记录 */
    @JpaQuery
    public String findRemarkBySourceIdAndSourceTypeSortByIdDesc(Long sourceId, int sourceType) {
        return null;
    }

    /** 获得线索的最新备注 */
    public String findNewestRemarkByClueId(Long id) {
        return findRemarkBySourceIdAndSourceTypeSortByIdDesc(id, 1);
    }
}

findNewestRemarkByClueId()方法需要调用类中的findRemarkBySourceIdAndSourceTypeSortByIdDesc()方法,问题是findRemarkBySourceIdAndSourceTypeSortByIdDesc()进行了AOP拦截,findNewestRemarkByClueId()在类中直接调用findRemarkBySourceIdAndSourceTypeSortByIdDesc()方法,将不会经过AOP拦截

工具类

写了一个工具类来解决自己调用自己的问题:

/** spring aop的辅助工具类 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class Aops {
    /**
     * 为了解决循环aop调用,要使用这个方法。另:spring默认的代理必须为cglib,且exposeProxy=true <br>
     * 用法:
     * 
     * <pre>
     * Aops.getSelf(this)
     * </pre>
     * 
     * @param t
     *            t一般入参为this,而this只能是类对象,不可能是代理类,这一点要注意
     */
    @SuppressWarnings("unchecked")
    public static <T> T getSelf(T t) {
        try {
            T curT = (T) AopContext.currentProxy();
            if (curT.getClass().getSuperclass().equals(t.getClass())) { // 有时出现currentProxy和t类型不一致,这里做一下判断
                return curT;
            }
        } catch (IllegalStateException e) {
            // 一般会报错:Cannot find current proxy: Set 'exposeProxy' property on
            // Advised to 'true' to make it available.
            // 此时表明这个类中没有aop方法,直接返回t即可
        }
        return t;
    }
}

上面的代码这样改:

@Repository
public class ErpRemarkRecordDao extends BaseDao<ErpRemarkRecord> {

    @Override
    protected String getTableName() {
        return "erp_remark_record";
    }

    /** 获得最新沟通记录 */
    @JpaQuery
    public String findRemarkBySourceIdAndSourceTypeSortByIdDesc(Long sourceId, int sourceType) {
        return null;
    }

    /** 获得线索的最新备注 */
    public String findNewestRemarkByClueId(Long id) {
        return Aops.getSelf(this).findRemarkBySourceIdAndSourceTypeSortByIdDesc(id, 1);
    }
}

Aops.getSelf(this)获得代理对象,而非当前对象。

需要注意的是,Spring容器中AOP的配置必须为cglib代理(不能用Java Proxy),且exposeProxy=true。
如果用的是Spring Boot,需要在启动类加上注解:

@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)

转载于:https://my.oschina.net/lizaizhong/blog/1611165

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值