You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用指定Repository方法时获取entityManager并合并两个切点的实现方案

解决方案

要实现仅当MyRepo方法被调用时才触发EntityManager的filter设置逻辑,避免无关调用触发catch分支,有两种可行方案:


方案1:使用AspectJ cflow 控制流切点(需要原生AspectJ支持)

利用AspectJ的cflow指示符匹配处于MyRepo方法调用流中的createEntityManager调用,直接合并两个切点逻辑,无需额外状态管理:

@Pointcut("execution(* com.package.repository.MyRepo.*(..))")
public void insideRepository() {}

@Pointcut("execution(* javax.persistence.EntityManagerFactory+.createEntityManager(..))")
public void createEntityManager() {}

// 组合切点:仅当createEntityManager发生在MyRepo方法的调用流程中时匹配
@Pointcut("createEntityManager() && cflow(insideRepository())")
public void createEntityManagerInRepoFlow() {}

@Before("insideRepository()")
public void enableFilter(JoinPoint jp) {
    System.out.println("Inside repo");
}

@AfterReturning(pointcut = "createEntityManagerInRepoFlow()", returning = "entityManager")
public void enableFilter(EntityManager entityManager) {
    // 仅MyRepo调用时才会进入该逻辑,确认场景必需要filter的话可以直接去掉try-catch
    entityManager.unwrap(Session.class).enableFilter("myFilter");
}

如果你的项目已经启用了原生AspectJ编译/织入,优先选择该方案,逻辑更简洁。


方案2:基于ThreadLocal状态标记(兼容Spring AOP默认环境)

如果你用的是Spring默认的代理模式AOP(不支持cflow指示符),可以用ThreadLocal存储当前线程是否处于MyRepo调用状态,在EntityManager创建后先判断状态再执行filter设置:

// 线程隔离的状态标记,记录当前线程是否处于MyRepo方法调用中
private static final ThreadLocal<Boolean> IN_REPO_CALL = ThreadLocal.withInitial(() -> false);

@Pointcut("execution(* com.package.repository.MyRepo.*(..))")
public void insideRepository() {}

@Pointcut("execution(* javax.persistence.EntityManagerFactory+.createEntityManager(..))")
public void createEntityManager() {}

@Before("insideRepository()")
public void markRepoCallStart() {
    IN_REPO_CALL.set(true);
}

// 无论MyRepo方法执行成功还是抛出异常,都要清空标记,避免内存泄漏和状态误判
@After("insideRepository()")
public void markRepoCallEnd() {
    IN_REPO_CALL.remove();
}

@AfterReturning(pointcut = "createEntityManager()", returning = "entityManager")
public void enableFilter(EntityManager entityManager) {
    // 非MyRepo调用场景直接跳过逻辑
    if (!IN_REPO_CALL.get()) {
        return;
    }
    try {
        entityManager.unwrap(Session.class).enableFilter("myFilter");
    } catch (Exception e) {
        System.out.println("No filter myFilter for this entity");
    }
}

内容的提问来源于stack exchange,提问作者SBDev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 11:45:10