Locked History Actions

Diff for "guice/AOP"

Differences between revisions 2 and 3
Deletions are marked like this. Additions are marked like this.
Line 73: Line 73:

== クラスとメソッド名を指定する例 ==
{{{
import java.lang.reflect.*;

import org.aopalliance.intercept.*;

import com.google.inject.*;
import com.google.inject.matcher.*;


public class Sample {

  public static class Greeting {
    public void hello() {
      System.out.println("hello, world");
    }
    public void setHello() {
      System.out.println("setHello");
    }
  }
  
  public static class SubGreeting extends Greeting {
    public void setHi() {
      System.out.println("setHi");
    }
  }

  public static class GoodBye {
    public void setGoodsBye() {
      System.out.println("setGoodBye");
    }
  }
  
  public static void main(String[]args) throws Exception {
    Injector injector = Guice.createInjector(new AbstractModule() {
      @Override protected void configure() {
        this.bindInterceptor(
            Matchers.subclassesOf(Greeting.class),
            new MethodNameMatcher(),
            new MethodInterceptor() {
              public Object invoke(MethodInvocation invocation) throws Throwable {
                System.out.println("before --- " + invocation.getMethod().getName());
                Object r = invocation.proceed();
                System.out.println("after --- " + invocation.getMethod().getName());
                return r;
              }
            }
        );
      }
    });
    Greeting greeting = injector.getInstance(Greeting.class);
    greeting.hello();
    greeting.setHello();
    SubGreeting subGreeting = injector.getInstance(SubGreeting.class);
    subGreeting.setHi();
    GoodBye goodBye = injector.getInstance(GoodBye.class);
    goodBye.setGoodsBye();
  }
  
  public static class MethodNameMatcher extends AbstractMatcher<Method>{
    public boolean matches(Method t) {
      if (t.getName().startsWith("set")) return true;
      return false;
    }
  }
}
}}}
実行結果は以下
{{{
hello, world
before --- setHello
setHello
after --- setHello
before --- setHi
setHi
after --- setHi
setGoodBye
}}}

AOPの使い方

簡単なサンプル

import java.lang.annotation.*;

import org.aopalliance.intercept.*;

import com.google.inject.*;
import com.google.inject.matcher.*;


public class Sample {

  /** インターセプトするメソッドの目印となるアノテーション */
  @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD)
  @interface DebugTrace {}

  /** インターセプト対象のメソッドを持つクラス */
  public static class Greeting  {

    @DebugTrace
    public void hello() {
      System.out.println("hello, world");
    }
  }

  /** インターセプタ定義 */
  public static class DebugTracer implements MethodInterceptor {
    public Object invoke(MethodInvocation invocation) throws Throwable {
      System.out.println("before ");
      Object r = invocation.proceed();
      System.out.println("after");
      return r;
    }
  }
  
  /** テスト */
  public static void main(String[]args) {
    Injector injector = Guice.createInjector(
        new AbstractModule() {
          protected void configure() {
            bindInterceptor(
                Matchers.any(), 
                Matchers.annotatedWith(DebugTrace.class), 
                new DebugTracer()
            );
          }
        }
    );
    
    Greeting greeting = injector.getInstance(Greeting.class);    
    greeting.hello();

    System.out.println("");
    System.out.println("" + greeting.getClass());
    System.out.println("" + greeting.getClass().getClassLoader());
    System.out.println("" + Sample.class.getClassLoader());
  }
}

実行結果は以下

before 
hello, world
after

class aop.Sample$Greeting$$EnhancerByGuice$$c979486
sun.misc.Launcher$AppClassLoader@a90653
sun.misc.Launcher$AppClassLoader@a90653

クラスとメソッド名を指定する例

import java.lang.reflect.*;

import org.aopalliance.intercept.*;

import com.google.inject.*;
import com.google.inject.matcher.*;


public class Sample {

  public static class Greeting  {    
    public void hello() {
      System.out.println("hello, world");
    }    
    public void setHello() {      
      System.out.println("setHello");
    }
  }
  
  public static class SubGreeting extends Greeting {
    public void setHi() {
      System.out.println("setHi");
    }
  }

  public static class GoodBye {
    public void setGoodsBye() {
      System.out.println("setGoodBye");
    }    
  }
  
  public static void main(String[]args) throws Exception {
    Injector injector = Guice.createInjector(new AbstractModule() {
      @Override protected void configure() {
        this.bindInterceptor(
            Matchers.subclassesOf(Greeting.class),
            new MethodNameMatcher(),
            new MethodInterceptor() {
              public Object invoke(MethodInvocation invocation) throws Throwable {
                System.out.println("before --- " + invocation.getMethod().getName());
                Object r = invocation.proceed();
                System.out.println("after --- " + invocation.getMethod().getName());
                return r;
              }
            }
        );
      }
    });
    Greeting greeting = injector.getInstance(Greeting.class);
    greeting.hello();
    greeting.setHello();
    SubGreeting subGreeting = injector.getInstance(SubGreeting.class);
    subGreeting.setHi();
    GoodBye goodBye = injector.getInstance(GoodBye.class);
    goodBye.setGoodsBye();
  }
  
  public static class  MethodNameMatcher extends AbstractMatcher<Method>{
    public boolean matches(Method t) {
      if (t.getName().startsWith("set")) return true;
      return false;
    }
  }
}

実行結果は以下

hello, world
before --- setHello
setHello
after --- setHello
before --- setHi
setHi
after --- setHi
setGoodBye