Google Guice - AOP


AOP, programowanie zorientowane na aspekt polega na rozbiciu logiki programu na odrębne części zwane tak zwanymi problemami. Funkcje, które obejmują wiele punktów aplikacji, nazywane są zagadnieniami przekrojowymi i te zagadnienia przekrojowe są koncepcyjnie oddzielone od logiki biznesowej aplikacji. Istnieje wiele typowych dobrych przykładów aspektów, takich jak logowanie, audyt, transakcje deklaratywne, bezpieczeństwo, buforowanie itp.

Kluczową jednostką modułowości w OOP jest klasa, podczas gdy w AOP jednostką modułowości jest aspekt. Dependency Injection pomaga oddzielić obiekty aplikacji od siebie, a AOP pomaga oddzielić problemy związane z cięciem krzyżowym od obiektów, na które mają one wpływ. AOP jest jak wyzwalacze w językach programowania, takich jak Perl, .NET, Java i inne. Guice zapewnia przechwytywacze do przechwytywania aplikacji. Na przykład, gdy metoda jest wykonywana, możesz dodać dodatkowe funkcje przed lub po wykonaniu metody.

Ważne zajęcia

  • Matcher- Matcher to interfejs do akceptowania lub odrzucania wartości. W Guice AOP potrzebujemy dwóch dopasowań: jednego do określenia, które klasy uczestniczą, a drugiego do metod tych klas.

  • MethodInterceptor- MethodInterceptors są wykonywane, gdy wywoływana jest metoda dopasowania. Mogą sprawdzić wywołanie: metodę, jej argumenty i instancję odbierającą. Możemy wykonać logikę przekrojową, a następnie delegować do metody bazowej. Na koniec możemy sprawdzić zwracaną wartość lub wyjątek i zwrócić.

Przykład

Utwórz klasę Java o nazwie 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;
   }
}

Wynik

Skompiluj i uruchom plik, możesz zobaczyć następujące dane wyjściowe.

Before checkSpelling
Inside checkSpelling.
After checkSpelling