Method Interceptor on private methods

我们两清 提交于 2019-12-21 16:21:43

问题


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.


回答1:


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.




回答2:


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.




回答3:


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;
}



回答4:


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.



来源:https://stackoverflow.com/questions/3627005/method-interceptor-on-private-methods

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!