Google Guice - AOP


AOP, la programmazione orientata agli aspetti comporta la scomposizione della logica del programma in parti distinte chiamate cosiddette preoccupazioni. Le funzioni che si estendono su più punti di un'applicazione sono chiamate preoccupazioni trasversali e queste preoccupazioni trasversali sono concettualmente separate dalla logica di business dell'applicazione. Esistono vari buoni esempi comuni di aspetti come registrazione, verifica, transazioni dichiarative, sicurezza, memorizzazione nella cache, ecc.

L'unità chiave della modularità in OOP è la classe, mentre in AOP l'unità di modularità è l'aspetto. L'inserimento delle dipendenze ti aiuta a disaccoppiare gli oggetti dell'applicazione l'uno dall'altro e AOP ti aiuta a disaccoppiare i problemi di cross-cutting dagli oggetti che influenzano. AOP è come i trigger nei linguaggi di programmazione come Perl, .NET, Java e altri. Guice fornisce intercettori per intercettare un'applicazione. Ad esempio, quando viene eseguito un metodo, è possibile aggiungere funzionalità extra prima o dopo l'esecuzione del metodo.

Classi importanti

  • Matcher- Matcher è un'interfaccia per accettare o rifiutare un valore. In Guice AOP, abbiamo bisogno di due matcher: uno per definire quali classi partecipano e un altro per i metodi di quelle classi.

  • MethodInterceptor- MethodInterceptor vengono eseguiti quando viene chiamato un metodo di corrispondenza. Possono ispezionare la chiamata: il metodo, i suoi argomenti e l'istanza ricevente. Possiamo eseguire una logica trasversale e quindi delegare al metodo sottostante. Infine, possiamo esaminare il valore o l'eccezione restituiti e restituire.

Esempio

Crea una classe java denominata GuiceTester.

GuiceTester.java

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.matcher.Matchers;

public class GuiceTester {
   public static void main(String[] args) {
      Injector injector = Guice.createInjector(new TextEditorModule());
      TextEditor editor = injector.getInstance(TextEditor.class);
      editor.makeSpellCheck(); 
   } 
}

class TextEditor {
   private SpellChecker spellChecker;

   @Inject
   public TextEditor(SpellChecker spellChecker) {
      this.spellChecker = spellChecker;
   }

   public void makeSpellCheck(){
      spellChecker.checkSpelling();
   }
}

//Binding Module
class TextEditorModule extends AbstractModule {

   @Override
   protected void configure() {
      bind(SpellChecker.class).to(SpellCheckerImpl.class);
      bindInterceptor(Matchers.any(), 
         Matchers.annotatedWith(CallTracker.class), 
         new CallTrackerService());
   } 
}

//spell checker interface
interface SpellChecker {
   public void checkSpelling();
}

//spell checker implementation
class SpellCheckerImpl implements SpellChecker {

   @Override @CallTracker
   public void checkSpelling() {
      System.out.println("Inside checkSpelling." );
   } 
}

@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD)
@interface CallTracker {}

class CallTrackerService implements MethodInterceptor  {

   @Override
   public Object invoke(MethodInvocation invocation) throws Throwable {
      System.out.println("Before " + invocation.getMethod().getName());
      Object result = invocation.proceed();
      System.out.println("After " + invocation.getMethod().getName());
      return result;
   }
}

Produzione

Compila ed esegui il file, potresti vedere il seguente output.

Before checkSpelling
Inside checkSpelling.
After checkSpelling