Google Guice-AOP


AOP、アスペクト指向プログラミングでは、プログラムロジックをいわゆる懸念事項と呼ばれる別個の部分に分解する必要があります。アプリケーションの複数のポイントにまたがる機能は横断的関心事と呼ばれ、これらの横断的関心事は概念的にアプリケーションのビジネスロジックから分離されています。ロギング、監査、宣言型トランザクション、セキュリティ、キャッシングなどの側面のさまざまな一般的な良い例があります。

OOPのモジュール性の主要な単位はクラスですが、AOPのモジュール性の単位はアスペクトです。依存性注入は、アプリケーションオブジェクトを相互に分離するのに役立ち、AOPは、横断的関心事をそれらが影響するオブジェクトから分離するのに役立ちます。AOPは、Perl、.NET、Javaなどのプログラミング言語のトリガーのようなものです。Guiceは、アプリケーションをインターセプトするためのインターセプターを提供します。たとえば、メソッドが実行されるときに、メソッドの実行の前後に機能を追加できます。

重要なクラス

  • Matcher-マッチャーは、値を受け入れるか拒否するためのインターフェースです。Guice AOPでは、2つのマッチャーが必要です。1つは参加するクラスを定義するためのもので、もう1つはそれらのクラスのメソッド用です。

  • MethodInterceptor-MethodInterceptorsは、マッチングメソッドが呼び出されたときに実行されます。彼らは呼び出しを検査することができます:メソッド、その引数、および受信インスタンス。横断的なロジックを実行してから、基礎となるメソッドに委任することができます。最後に、戻り値または例外を検査して返す場合があります。

GuiceTesterという名前のJavaクラスを作成します。

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;
   }
}

出力

ファイルをコンパイルして実行すると、次の出力が表示される場合があります。

Before checkSpelling
Inside checkSpelling.
After checkSpelling