com.google.inject.Module を実装するクラスを用意して
configure(com.google.inject.Binder)メソッドで
bindInterceptorメソッドによりマッチング条件でインターセプトの
バインド定義するわけだが、任意のアノテーションのアノテーションで
マッチ条件とする場合、以下のようなstatic メソッドを用意する。
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import com.google.inject.matcher.AbstractMatcher;
import com.google.inject.matcher.Matcher;
import com.google.inject.util.Objects;
/**
* インターセプトMatcher .
* @Intercept アノテーションで指定する value 値と指定文字列が一致する時
* にインターセプトする。
* 例)ALogic の中のメソッドに、@Intercept("aaa") を付けた
* メソッドを、ALogicIntercepter というインターセプタを実行したい場合は、
* 以下のようにする。
* binder.bindInterceptor(Matchers.inPackage(ALogic.class.getPackage())
* ,InterceptMatcher.annotatedWith(Intercept.class,"aaa")
* ,new ALogicIntercepter());
* InterceptMatcher.annotatedWith(Intercept.class,string) stringは、重複不可!
*/
public final class InterceptMatcher {
private InterceptMatcher(){}
/**
* @Intercept アノテーションで指定する value 値と指定文字列が一致する時に
* インターセプトする。
* @param annotationType
* @param reqStr 指定文字列 JVM内でユニークなKey
* @return Matcher<AnnotatedElement>
*/
public static Matcher<AnnotatedElement>
annotatedWith(final Class<? extends Annotation> annotationType
,final String reqStr){
Objects.nonNull(annotationType,"annotation type");
return new AbstractMatcher<AnnotatedElement>(){
public boolean matches(AnnotatedElement element) {
Annotation annotation = element.getAnnotation(annotationType);
if (annotation==null){
return false;
}
return ((Intercept)annotation).value().equals(reqStr);
}
@Override
public String toString() {
return "annotatedWith("+annotationType.getSimpleName()
+".class,"+reqStr+")";
}
};
}
}
// インターセプトさせるメソッドアノテーション import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Intercept{ String value(); } // ALogicインターフェースと実装 public interface ALogic{ public void action(); } public class ALogicImpl implements ALogic{ /* * ALogic#action()に、@Intercept を付与する。 */ @Intercept("aaa") public void action(){ System.out.println("■ ALogic#action()"); } } // バインド定義 import com.google.inject.Binder; import com.google.inject.Module; import com.google.inject.matcher.Matchers; import com.google.inject.name.Names; public class AbcModule implements Module{ public void configure(Binder binder){ binder.bind(ALogic.class).annotatedWith(Names.named("alogic")) .to(ALogicImpl.class); // インターセプター // InterceptMatcher.annotatedWith(Intercept.class,string) // の stringは、重複セット不可! // @Intercept("aaa") が、ALogicIntercepter によりインターセプトされる // ことを約束させる binder.bindInterceptor(Matchers.inPackage(ALogic.class.getPackage()) ,InterceptMatcher.annotatedWith(Intercept.class,"aaa") ,new ALogicIntercepter()); } } //======= インターセプターの準備 /* * インターセプター抽象クラス */ import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; public abstract class AbstarctIntercepter implements MethodInterceptor{ /** * 前処理 */ public abstract void preProcess(); /** * 後処理 */ public abstract void afterProcess(); /* インターセプト * @see org.aopalliance.intercept.MethodInterceptor#invoke( * org.aopalliance.intercept.MethodInvocation) */ public Object invoke(MethodInvocation m) throws Throwable{ try{ // 前処理実行 this.preProcess(); // 処理実行 Object obj = m.proceed(); // 後処理実行 this.afterProcess(); return obj; }catch(Exception e){ throw e; }finally{ } } } // AbstarctIntercepter の具象クラス→ ALogicIntercepter public class ALogicIntercepter extends AbstarctIntercepter{ @Override public void afterProcess(){ System.out.println("■ ALogicIntercepter#afterProcess()"); } @Override public void preProcess(){ System.out.println("■ ALogicIntercepter#preProcess()"); } } //======= 実行するDIクラス import com.google.inject.Inject; import com.google.inject.name.Named; public class AClient{ // ALogic は、ALogicImplで生成される。 @Inject @Named("alogic") private ALogic alogic; public void execA(){ this.alogic.action(); } } //====== DIを実施して実行する。 import com.google.inject.Guice; import com.google.inject.Injector; : : Injector injector = Guice.createInjector(new AbcModule()); AClient client = injector.getInstance(AClient.class); client.exeA();