【问题标题】:Call different proxyied method from Spring Aspect从 Spring Aspect 调用不同的代理方法
【发布时间】:2018-03-28 17:45:03
【问题描述】:

我有两个不同的方面。如何保证从某一方面调用方法时,还是要经过代理链?

相关代码如下:

内在方面:

@Around("withinReplicatedRepository() && entityMethod() && insertMethod()")
public Object trackInsert(ProceedingJoinPoint jp) throws Throwable {
    return trackChange(jp, ChangeType.INSERT, jp.getArgs()[0]);
}

方面:

@Around("withinReplicatedRepository() && entityMethod() && autoSaveRepository() && saveMethod()")
public Object saveEntity(ProceedingJoinPoint jp) throws Throwable {
    TransactionUtil.ensureTransactional();

    Object entity = jp.getArgs()[0];
    AutoSaveRepository repository = (AutoSaveRepository)jp.getTarget();
    if (repository.exists(entity)) {
        repository.update(entity);
    } else {
        repository.insert(entity);
    }
    return null;
}

用法:

AutoSaveRepository<MyEntity> repo = ...;
repo.save(entity);

我的问题是 jp.getTarget() 将返回原始类,因此 repository.insert() 不会被 trackInsert 捕获。

【问题讨论】:

  • ... 中的AutoSaveRepository&lt;MyEntity&gt; repo = ...; 是什么? AutoSaveRepository 是单例 bean 吗?那么使用getBean(..) 应该很容易得到这个bean。
  • 不是单例,AutoSaveRepository 有多个实例。

标签: java spring spring-aop


【解决方案1】:

你可以试试

AopContext.currentProxy()

Javadoc

不过,前提是您激活代理曝光:

  • 自 Spring 3.0.3 起,您可以在 XML 中通过
    &lt;aop:aspectj-autoproxy expose-proxy="true"/&gt; 执行此操作。
  • 在注释样式的配置中,您可以从 4.3.1 开始通过
    @EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
    参见Javadoc

【讨论】:

  • 我在其他线程中看到了这一点。但是AopContext.currentProxy() 不被认为是一种hack吗?
  • 它记录在 Spring 的 Javadoc 中。你会怎么想?但是,如果您有另一种获取 bean 实例(代理)的方法,请使用该方法。或者,使用带有 LTW 的完整 AspectJ 并摆脱 Spring 的代理。
  • 确实感觉有点像黑客(也请参阅此答案:stackoverflow.com/a/7482767/353563),但如果这是唯一的方法,那么我没有太多选择。理想情况下,ProceedingJoinPoint 中会有获取原始对象的方法,但我明白为什么很难实现。
  • 所以因为另一个答案中的一个人说这意味着它是一个黑客?实际上,Spring AOP 确实有其局限性。与 AspectJ 相比,它更像是“AOP lite”,但如果您不想切换,则必须接受提供的内容。 :-)
猜你喜欢
  • 1970-01-01
  • 2019-10-10
  • 1970-01-01
  • 1970-01-01
  • 2017-11-19
  • 1970-01-01
  • 2017-10-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多