Guice 简明教程

Google Guice - AOP

面向方面的编程 OAP,意味着将程序逻辑分解成不同的部分,所谓的关注点。跨越应用程序多个点的函数称为横切关注点,并且这些横切关注点在概念上与应用程序的业务逻辑是分离的。横切面有很多常见的例子,例如日志记录、审计、声明式交易、安全、缓存等。

面向对象编程中模块化的关键单元是类,而面向方面编程中模块化的单元是横切面。依赖注入帮助用户解耦应用程序对象,并且面向方面编程帮助用户解耦横切关注点和它们影响的对象。面向方面编程类似于 Perl、.NET、Java 和其他编程语言中的触发器。Guice 提供拦截器来拦截应用程序。例如,在执行方法时,用户可以在方法执行之前或之后添加额外功能。

Important Classes

  1. Matcher - Matcher 是接受或拒绝值的界面。在 Guice AOP 中,我们需要两个匹配器:一个用来定义参与的类,另一个针对这些类的函数。

  2. MethodInterceptor - 调用匹配方法时,执行 MethodInterceptors。它们可以检查调用:方法、其参数、以及方法接收的实例。我们可以执行横切逻辑,然后将其委托给底层方法。最后,我们可以检查返回值或异常并返回。

Example

创建名为 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;
   }
}

Output

编译并运行文件,用户可以看到以下输出。

Before checkSpelling
Inside checkSpelling.
After checkSpelling