Argo源码阅读(三):Google-guice依赖注入框架

商华藏
2023-12-01

在Argo中用到了Google-guice依赖注入框架:http://code.google.com/p/google-guice/


Google-guice 依赖注入框架主要由@Inject注解、AbstractModule基类组成

 

//google code上的例子

RealBillingService类构造时依赖CreditCardProcessor和TransactionLog接口,添加@Inject注解后将由Guice调用RealBillingService构造器。

class RealBillingService implements BillingService {
  private finalCreditCardProcessor processor;
  private finalTransactionLog transactionLog;

  @Inject
  RealBillingService(CreditCardProcessor processor,
      TransactionLog transactionLog){
    this.processor= processor;
    this.transactionLog= transactionLog;
  }

  @Override
  public Receipt chargeOrder(PizzaOrder order,CreditCard creditCard){
    ...
  }
}

 

AbstractModule构建Guice的object-graph,重载Configure方法实现接口和实现类的绑定

 

public class BillingModule extends AbstractModule {
  @Override 
  protected void configure() {

     /*
      * This tells Guice that whenever it sees a dependency on a TransactionLog,
      * it should satisfy the dependency using a DatabaseTransactionLog.
      */
    bind(TransactionLog.class).to(DatabaseTransactionLog.class);

     /*
      * Similarly, this binding tells Guice that when CreditCardProcessor is used in
      * a dependency, that should be satisfied with a PaypalCreditCardProcessor.
      */
    bind(CreditCardProcessor.class).to(PaypalCreditCardProcessor.class);
  }
}


由此也可以看出@Inject 和 bind是一起出现的 


用Module子类创建新的Guice注解器实例

 public static void main(String[] args) {
    /*
     * Guice.createInjector() takes your Modules, and returns a new Injector
     * instance. Most applications will call this method exactly once, in their
     * main() method.
     */
    Injector injector = Guice.createInjector(new BillingModule());

    /*
     * Now that we've got the injector, we can build objects.
     */
    RealBillingService billingService = injector.getInstance(RealBillingService.class);
    ...
  }

 

 

Argo中的注入

public class Argo {

    public ArgoDispatcher init(ServletContext servletContext,
                               GroupConvention groupConvention) {
        …

        List<Module> modules = Lists.newArrayList();
        modules.add(new ArgoModule(this));

        Module groupModule = groupConvention.group().module();
        if (null != groupModule)
            modules.add(groupModule);

        Module projectModule = groupConvention.currentProject().module();
        if (null != projectModule)
            modules.add(projectModule);

        servletContext.log("preparing an injector");
        this.injector = buildInjector(modules);
        servletContext.log("injector completed");

        …
    }


    private Injector buildInjector(List<Module> modules) {
        return Guice.createInjector(modules);
    }

public class ArgoModule extends AbstractModule {

    @Override
    protected void configure() {

        bind(ServletRequest.class).to(HttpServletRequest.class);
        bind(ServletResponse.class).to(HttpServletResponse.class);

        bind(BeatContext.class)
                .annotatedWith(ArgoSystem.class)
                .to(DefaultBeatContext.class);

        bind(ActionResult.class)
                .annotatedWith(Names.named("HTTP_STATUS=404"))
                .toInstance(StatusCodeActionResult.defaultSc404);

        bind(ActionResult.class)
                .annotatedWith(Names.named("HTTP_STATUS=405"))
                .toInstance(StatusCodeActionResult.defaultSc405);

        bind(Action.class).annotatedWith(StaticActionAnnotation.class)
                .to(StaticFilesAction.class);

        bind(ClientContext.class).to(DefaultClientContext.class);
        bind(Model.class).to(DefaultModel.class);

        bind(MultipartConfigElement.class)
                .toProvider(DefaultMultipartConfigElementProvider.class)
                .in(Singleton.class);

        // bind all controllers.
        for (Class<? extends ArgoController> clazz : argo.getControllerClasses())
            bind(clazz).in(Singleton.class);
}
}


由此可见,Argo中的init方法首先构造Module实例集合,然后调用Guice的CreateInjector方法绑定对应的接口和实现类。

 

argo.getControllerClasses()中的Module应该是在Argo框架注解过的集合。

 类似资料: