Warm tip: This article is reproduced from serverfault.com, please click

java-访问 spring bean 代理引用本身

(java - Accessing spring bean proxy reference itself)

发布于 2019-02-21 06:36:35

我有一个问题@Cacheable@CacheEviction注释。当我在声明它们的 bean 中调用这些方法时,aop 部分没有被执行。

这样做的根本原因是 bean 访问自己的实例本身,而不是访问 spring 代理。

我读过这个问题,据说在大多数情况下,访问代理的 bean 不是必需的。

可能这些答案对我有用。问题是:

有没有其他方法可以使带注释的方法起作用?或者听起来我找到了一个需要访问代理本身的 bean 的好理由?

Questioner
Mayday
Viewed
0
kriegaex 2021-01-11 23:26:52

这个问题已经在 SO 上被问过和回答过几十次了。

正如 Spring 用户手册中详细记录的那样,自调用不能与 Spring AOP 一起使用,因为 Spring AOP 使用代理。所以如果你想让自调用触发一个方面,请通过 LTW (load-time weaving)切换到完整的AspectJ它适用于原始 bean,不使用任何代理。


由于这个旧问题中的新活动 - 有一个奇怪的downvote和一个更奇怪的错误答案 - 我只想提一下,如果你想避免使用原生AspectJ而是作为(非常蹩脚和反AOP)解决方法想让你的组件能够感知代理,当然你可以使用自注入并使用自动连接的代理引用缓存方法,如下所示:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;

@Component
public class MyComponent {
  @Autowired
  MyComponent myComponent;

  public void doSomething() {
    System.out.println(myComponent.doCacheable());
    System.out.println(myComponent.doCacheable());
    System.out.println(myComponent.doCacheable());
  }

  @Cacheable("myCache")
  public String doCacheable() {
    return "" + System.nanoTime();
  }
}

调用doSomething()MyComponent豆应产生的输出是这样的:

247760543178800
247760543178800
247760543178800

这证明缓存是这样工作的。相反,如果你只有三行System.out.println(doCacheable());或来自其他答案的奇怪,荒谬的变体System.out.println(MyComponent.this.doCacheable());,那么你将在控制台上获得三个不同的值,即不会缓存任何内容。