views:

94

answers:

3

Hello, everybody.
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.

+2  A: 

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.

Cid54
Correct, Spring AOP works with dynamic proxies, meaning you can only intercept methods that are exposed in an interface and when the proxy is able to delegate directly to the exposed method.
nkr1pt
see http://forum.springsource.org/archive/index.php/t-34372.html
Cid54
This only the case for JDK dynamic proxies. Spring AOP can also work with CGLIB subclass proxies, in which case self-invocation of public methods works just fine.
skaffman
thanks, i thought so too, but wanted to be sure.
foret
+1  A: 

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.

skaffman
A: 

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