私有方法上的方法拦截器

发布于 2024-09-16 16:20:20 字数 369 浏览 4 评论 0 原文

这是一个问题:我有方法digest(byte[] data)。它应该是私有的,因为我们真的不需要在课堂之外使用它,但是如果我将其公开,如果有帮助的话,我就不会死。
问题是:我可以以某种方式附加拦截器吗?问题是它不是像 getBean('MyBean').digest() 那样调用的,而是通过 getBean('MyBean').sign(data) 调用的,其中标志就像

public byte[] sign(byte[] data){
   ...
   b = digest(data);
   ...
   return signature;
}

Thx 一样。

Here is a question: I have method digest(byte[] data). It should be private, because we really don't need it outside a class, however i'll not die if i make it public, if it helps.
The question is: can i somehow attach interceptor to it? The thing is that it is not called like getBean('MyBean').digest(), it is called through getBean('MyBean').sign(data) where sign is smth like

public byte[] sign(byte[] data){
   ...
   b = digest(data);
   ...
   return signature;
}

Thx.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梦巷 2024-09-23 16:20:20

即使该方法是公共的,Spring 也无法拦截从包含该方法的对象内部进行的方法调用。要实现这一点,您必须使用 AspectJ。

Even if the method is public, Spring can't intercept method calls who are made from within the object containing the method. To achieve this, you would have to use AspectJ.

回首观望 2024-09-23 16:20:20

有点完整的 AspectJ 巫术,您需要将拦截的方法设为 public。如果您不想将 bean 的 digest() 方法公开为 public,但仍想应用拦截器,那么我建议重构您的代码以提取摘要逻辑输出到一个实现新摘要接口的单独类中,并将拦截器应用于该类。

这有点笨拙,但它确实迫使你分离你的关注点,这并不是坏事。

Sort of full AspectJ voodoo, you need to make your intercepted method public. If you don't want to expose the digest() method of your bean as public, but still want to apply interceptors, then I suggest refactoring your code to extract the digest logic out into a separate class that implements a new digest interface, and apply the interceptors to that.

It's a bit clumsy, but it does force you to separate your concerns, which is not bad thing.

⊕婉儿 2024-09-23 16:20:20

实现您想要的效果的另一种方法是创建一个 Digester 类并拦截对其digest() 方法的调用:

public interface Digester {
  public Foo digest(byte[] data);
}

class DigesterImpl implements Digester {
  public Foo digest(byte[] data) {...}
}

然后在您的 spring 代码中,您将一个代理 DigesterImpl 注入您的类并调用它:

private final Digester digester;

MyClass(Digester digester) {
  this.digester = digester;
}

public byte[] sign(byte[] data){
   ...
   b = digester.digest(data);
   ...
   return signature;
}

Another way of achieving what you want is to create a Digester class and intercept the calls to it's digest() method:

public interface Digester {
  public Foo digest(byte[] data);
}

class DigesterImpl implements Digester {
  public Foo digest(byte[] data) {...}
}

Then in your spring code you inject a proxied DigesterImpl to your class and call it:

private final Digester digester;

MyClass(Digester digester) {
  this.digester = digester;
}

public byte[] sign(byte[] data){
   ...
   b = digester.digest(data);
   ...
   return signature;
}
枕头说它不想醒 2024-09-23 16:20:20

这里要理解的关键是,当使用 Aspect 编程时,对该对象引用的方法调用将是对代理的调用,因此代理将能够委托给所有拦截器(建议)与该特定方法调用相关。

但是,一旦调用最终到达目标对象,它可能对自身进行的任何方法调用(例如 Digest(Data))都将针对 this 引用而不是代理进行调用 。

这具有重要意义。这意味着自调用不会导致与方法调用相关的建议有机会执行。但有一种方法可以做到这一点:

public byte[] sign(byte[] data){
   ...
   b = (Digester)AopContext.currentProxy()).Digest(Data);
   ...
   return signature;
}

这将您的代码与 Spring AOP 完全耦合,并且它使类本身意识到它正在 AOP 上下文中使用这一事实,这是不可行的AOP 的。

The key thing to understand here is that the when using Aspect programming the method calls on that object reference will be calls on the proxy, and as such the proxy will be able to delegate to all of the interceptors (advice) that are relevant to that particular method call.

However, once the call has finally reached the target object, any method calls that it may make on itself, such as Digest(Data), are going to be invoked against the this reference, and not the proxy.

This has important implications. It means that self-invocation is not going to result in the advice associated with a method invocation getting a chance to execute. But there is a way to do it:

public byte[] sign(byte[] data){
   ...
   b = (Digester)AopContext.currentProxy()).Digest(Data);
   ...
   return signature;
}

This totally couples your code to Spring AOP, and it makes the class itself aware of the fact that it is being used in an AOP context, which flies in the face of AOP.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文