Метод Interceptor на приватные методы - PullRequest
5 голосов
/ 02 сентября 2010

Вот вопрос: у меня есть метод digest(byte[] data).Это должно быть приватно, потому что нам действительно не нужно это вне класса, однако я не умру, если я сделаю это публичным, если это поможет.Вопрос: могу ли я как-нибудь прикрепить к нему перехватчик?Дело в том, что он не называется как getBean('MyBean').digest(), он вызывается через getBean('MyBean').sign(data), где знак что-то вроде

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

Thx.

Ответы [ 4 ]

3 голосов
/ 02 сентября 2010

Даже если метод общедоступный, Spring не может перехватывать вызовы метода, которые сделаны из объекта, содержащего метод. Для этого вам нужно использовать AspectJ.

1 голос
/ 02 сентября 2010

Вроде полный AspectJ voodoo, вам нужно сделать перехваченный метод public. Если вы не хотите показывать метод digest() вашего компонента как public, но по-прежнему хотите применять перехватчики, тогда я предлагаю реорганизовать ваш код для извлечения логики дайджеста в отдельный класс, который реализует новый интерфейс дайджеста и примените к нему перехватчики.

Это немного неуклюже, но заставляет вас разделять свои проблемы, что не так уж и плохо.

0 голосов
/ 16 марта 2014

Ключевым моментом, который необходимо понять, является то, что при использовании Aspect программирования вызовы методов для этой ссылки на объект будут вызовами прокси-сервера, и, таким образом, прокси сможет делегировать всем перехватчикам (совет) которые имеют отношение к этому конкретному вызову метода.

Однако, как только вызов, наконец, достигнет целевого объекта, любые вызовы методов, которые он может сделать для себя, , такие как Digest (Data), будут вызываться с ссылкой this, а не с прокси .

Это имеет важные последствия. Это означает, что самовывоз не приведет к тому, что совет, связанный с вызовом метода, получит шанс на выполнение. Но есть способ сделать это:

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

Это полностью связывает ваш код с Spring AOP и позволяет самому классу осознать тот факт, что он используется в контексте AOP, который бросает вызов AOP.

0 голосов
/ 04 сентября 2010

Еще один способ достичь желаемого - создать класс Digester и перехватывать вызовы его метода digest ():

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

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

Затем в своем весеннем коде вы вводите проксируемый DigesterImpl в ваш класс и называете его:

private final Digester digester;

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

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