レベルエンター山本大のブログ

面白いプログラミング教育を若い人たちに

BLOCKVROCKリファレンス目次はこちら

Guice vs. SpringJavaConfig (2) Guice and AOP

Guice vs. Spring JavaConfig: A comparison of DI styles

DIスタイルの比較:Guice 対 SpringのJavaコードコンフィグ
http://jroller.com/page/habuma?entry=guice_vs_spring_javaconfig_a


■[翻訳]Guice vs. SpringJavaConfig (1) A Knight's tour of Guice

Guice and AOP GuiceAOP

At this point you've seen the basics of Guice injection. Now let's see how Guice does AOP.


ここまでで、Guiceの基本的なインジェクションを見てきました。さて、次にGuiceがどうやってAOPを行っているのかを見て行きましょう。


First, I implemented the MinstrelInterceptor as an AOP Alliance MethodInterceptor:


まずは、MinstrelInterceptorをAOPアライアンスのMethodInterceptorとして実装しました。

package com.springinaction.chapter01.knight;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class MinstrelInterceptor implements MethodInterceptor {
  
  public Object invoke(MethodInvocation mi) throws Throwable {

    Knight knight = (Knight) mi.getThis();

    System.out.println(
        "La la la, Sir " + knight.getName() + " is so brave!");
    Object rtn = mi.proceed();
    System.out.println("" +
        "Tee-he-he, he did " + mi.getMethod().getName());
    
    return rtn;
  }
}

Then, back in KnightModule.java, I had to bind the interceptor:


それから、KnightModule.javaに戻って、interceptorをバインドしました。

    bindInterceptor(
      any(), 
      annotatedWith(MinstrelIntercepted.class), 
      new MinstrelInterceptor()
    );

This effectively binds the MinstrelInterceptor to all methods that are annotated with @MinstrelIntercepted (another custom annotation) on all types ("any()"). I couldn't find any more straightforward way to create a "pointcut" other than to create a custom annotation and to bind the interceptor to it.

With the interceptor bound to @MinstrelInterceptor (on both types and methods), I had to change the KnightOfTheRoundTable to use the @MinstrelIntercepted annotation on the embarkOnQuest() method:


MinstrelInterceptorをすべてのメソッドにバインドする効果は、("any()"メソッドを使うことで)すべての型に対して、@MinstrelIntercepted(およびその他のカスタムアノテーション)によってアノテートされます。
私は、ポイントカットを作るために、このカスタムアノテーションを作ってインターセプターをバインドするというやりかた以上に直接的な方法をみつけることができませんでした。

(型とメソッドの両方に設定する)@MinstrelInterceptorにインターセプターをバインドして、embarkOnQuest()メソッドで@MinstrelInterceptedアノテーションを使うように、KnightOfTheRoundTableを変更しました。

  @MinstrelIntercepted
  public Object embarkOnQuest() throws QuestFailedException {
    return quest.embark();
  }

With the embarkOnQuest() method annotated and MinstrelInterceptor bound to the @MinstrelIntercepted annotation, any call to a KnightOfTheRoundTable's embarkOnQuest() method will result in the minstrel singing about the knight's exploits.

And that is, in a nutshell, how I implemented the knight/quest example using Guice. Again, the full source code for this example is available for download here.

Now let's see how I did the same thing using Spring JavaConfig.


embarkOnQuest()メソッドにアノテーションを設定して、MinstrelInterceptorを@MinstrelInterceptedアノテーションにバインドすることによって、KnightOfTheRoundTableのembarkOnQuest()メソッドに対するすべての呼び出しは、騎士の功績についてのmistral(吟遊詩人)の歌声をもたらすことになります。

そしてknight/questサンプルをGuiceを使って実装する方法は、簡単にいえば以上のようなところです。このサンプルの完全なソースコードここでダウンロードできます。

さて、次は同じことをSpring Java Configを使ってやってみましょう。

つづく