2010-09-02 17 views
5

Aquí hay una pregunta: Tengo el método digest(byte[] data). Debe ser privado, porque realmente no lo necesitamos fuera de una clase, sin embargo, no moriré si lo hago público, si me sirve.
La pregunta es: ¿de alguna manera puedo adjuntar un interceptor? La cosa es que no se llama así getBean('MyBean').digest(), se llama a través getBean('MyBean').sign(data) donde signo es algo bajo comoMétodo Interceptor en métodos privados

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

Thx.

+0

Intenté formatear su código, pero sigue siendo ilegal. Por favor, péguelo correctamente. – Bozho

Respuesta

3

Incluso si el método es público, Spring no puede interceptar las llamadas a métodos que se realizan desde dentro del objeto que contiene el método. Para lograr esto, deberías usar AspectJ.

+0

Correcto, Spring AOP funciona con proxies dinámicos, lo que significa que solo puede interceptar métodos que están expuestos en una interfaz y cuando el proxy puede delegar directamente en el método expuesto. – nkr1pt

+1

ver http://forum.springsource.org/archive/index.php/t-34372.html – Cid54

+1

Este es solo el caso de los proxys dinámicos JDK. Spring AOP también puede funcionar con proxies de subclases CGLIB, en cuyo caso la auto invocación de métodos públicos funciona bien. – skaffman

1

Tipo de vojido AspectJ lleno, debe realizar su método interceptado public. Si no desea exponer el método digest() de su bean como public, pero aún desea aplicar interceptores, sugiero refactorizar su código para extraer la lógica de resumen en una clase separada que implemente una nueva interfaz de resumen, y aplicar el interceptores a eso.

Es un poco torpe, pero te obliga a separar tus preocupaciones, lo cual no es malo.

0

Otra manera de lograr lo que desea es crear una clase digestor e interceptar las llamadas a su compendio método():

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

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

Luego, en el código de la primavera se inyecta un DigesterImpl proxy a su clase y la llamada que:

private final Digester digester; 

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

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

la clave para entender aquí es que el al utilizar Aspect programar el método de llamadas en esa referencia de objeto será pide a la delegación, y como tal, el proxy podrá delegar en todo el interceptores (a dvice) que son relevantes para esa llamada de método particular.

Sin embargo, una vez que la llamada finalmente ha alcanzado el objeto de destino, se invocará cualquier método invocado sobre él, como Digest (Datos), y no el proxy.

Esto tiene implicaciones importantes. Significa que la auto invocación no dará como resultado el asesoramiento asociado con una invocación a un método que tenga la oportunidad de ejecutarse. Pero hay una manera de hacerlo:

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

Esta totalmente parejas su código para Spring AOP, y hace que la propia clase consciente del hecho de que está siendo utilizado en un contexto de AOP, que va en contra de AOP.

Cuestiones relacionadas