back to top

AOP – Proxies – Guida Java Spring

Prima di passare a vedre come si creano gli aspect con i rispettivi advice e pointcut, è molto importante capire come funzionano i proxies. Un proxy non è altro che un wrapper (contenitore) che racchiude un oggetto ed espone tutti i medodi pubblici dell'oggetto stesso. Quando viene invocato un metodo sul proxy l'esecuzione reale del metodo viene delegata all'oggetto wrappato, rendendo così la presenza del proxy del tutto trasparente all'utente. I proxy che Spring usa per implementare AOP oltre al semplice delegare dei metodi si occupano anche della gestione dei vari advice.

Capiamo come agisce un proxy implementandone uno molto semplice. Prima di tutto creiamo una semplice interfaccia:

public interface SimpleInterface {

  public void f1();

  public void f2();
}

creaiamo anche una semplice implementazione:

public class SimplePojo implements SimpleInterface {

  @Override
  public void f1() {
    System.out.println("F1");
    f2();
  }

  @Override
  public void f2() {
    System.out.println("F2");
  }
}

Notiamo che il metodo f1() fa una chiamata al metodo f2(). Passiamo ora alla creazione del proxy; come già detto dobbiamo creare un contenitore di un oggetto ed esporre tutti i suoi metodi, quindi il proxy implementerà l'interfaccia SimpleInterface e poi delegherà tutte le chiamate ai metodi all'oggetto reale:

public class SimpleProxy implements SimpleInterface {

  private SimpleInterface delegate;

  public SimpleProxy(SimpleInterface delegate) {
    super();
    this.delegate = delegate;
  }

  @Override
  public void f1() {
    System.out.println("DELEGATING F1()");
    delegate.f1();
  }

  @Override
  public void f2() {
    System.out.println("DELEGATING F2()");
    delegate.f2();
  }
}

Nel nostro semplice esempio il proxy non fa altro che stampare un messaggio dove dice che sta delegando la chiamata.

Creaiamo ora un main di prova per vedere come funziona il nostro proxy:

public class Main {

  public static void main(String[] args) {
    //creo un instanza del bean 
    SimpleInterface realBean = new SimplePojo();

    System.out.println("##### bean #####");
    realBean.f1();
    System.out.println();
    realBean.f2();

    System.out.println();

    //creo un instanza del proxy
    SimpleInterface proxy = new SimpleProxy(new SimplePojo());

    System.out.println("##### proxy #####");
    proxy.f1();
    System.out.println();
    proxy.f2();
  }
}

Il primo blocco di codice darà il seguente output:

##### bean #####
F1
F2

F2

Ora ci si aspetterebbe che l'output del secondo blocco sia il seguente:

##### proxy #####
DELEGATING F1()
F1
DELEGATING F2()
F2

DELEGATING F2()
F2

Invce no! L’output sarà il seguente:

##### proxy #####
DELEGATING F1()
F1
F2

DELEGATING F2()
F2

Come possiamo vedere la chiamata che il metodo f1() fa al metodo f2() non passa per il proxy, poichè una volta che si è delegata l'esecuzione del metodo all'oggetto reale tutte le chiamate interne all'oggetto non saranno più intercettate dal proxy. Per questo motivo non si possono creare advice su metodi che vengono chiamati da altri metodi dell'oggetto, o meglio si possono creare solo se questi metodi vengono usati da oggetti esterni, poichè altrimenti l'advice non verrà mai eseguito.

Proxy
Pubblicità