使用Gin/Guice注入实例

3

在我的GWT项目中,我通常会有这种代码模式:

Menu errorMenu = new Menu(user, userController, -1);
Menu  searchMenu = new Menu(user, userController, 0);

errorView.setMenu(errorMenu);
searchView.setMenu(searchMenu);

如何在Gin/Guice中将Menu实例注入到ErrorView和其他“视图”中:

public ErrorView implements View {
 // Inject menu instance here
 private Menu menu;
}

这样的话,我就不必手动创建和设置对象了吗?
此外,对于Menu类,我该如何注入“user”和“userController”对象,以便每次实例化菜单时都不必传递它们。

由于我的应用程序中只有一个 User 和 UserController 实例,所以是否有一种方法也可以将其注入? - quarks
1个回答

10

通过这个教程http://code.google.com/p/google-gin/wiki/GinTutorial的帮助,你的问题看起来并不那么困难。你需要运行几个步骤将菜单实例注入到视图中。

  1. 在菜单字段上添加 @Inject 注解。

public ErrorView implements View {

  @Inject
  private Menu menu;
}

public SearchView implements View {

  @Inject
  private Menu menu;
}

但在这种情况下,在View对象初始化(在构造函数中)期间,菜单字段将为null。因此,我更喜欢将此字段添加到构造函数参数中。

public ErrorView implements View {

  private final Menu menu;

  @Inject
  public ErrorView(Menu menu) {
    this.menu = menu;
  }
}

public SearchView implements View {

  private final Menu menu;

  @Inject
  public SearchView(Menu menu) {
    this.menu = menu;
  }
}
当然,如果您的ErrorView构造函数有许多其他参数,它将无法工作,因为所有这些参数都需要被注入。
现在我们必须确保GIN知道ErrorView中的menu字段应该注入到new Menu(user, userController, -1) ,并且在SearchView中注入到new Menu(user, userController, 0)。我们可以通过以下几种方式来实现:
  • 向您的menu字段添加注解@Named("searchMenu")@Named("errorMenu")

  • public ErrorView implements View {
    
      @Inject
      @Named("errorMenu")
      private Menu menu;
    }
    
    或者
    public ErrorView implements View {
    
      private final Menu menu;
    
      @Inject
      public ErrorView(@Named("errorMenu") Menu menu) {
        this.menu = menu;
      }
    } 
    

    在你的GIN模块中,你应该提供这个注解的定义。

        public class ApplicationGinModule extends AbstractGinModule {
    
          protected void configure() {
            bind(Menu.class).annotatedWith(Names.named("errorMenu")).to(DefaultErrorMenu.class);
            bind(Menu.class).annotatedWith(Names.named("searchMenu")).to(DefaultSearchMenu.class);
    
            //assume that User and UserController classes have default constructors  
            //otherwise you should provide correct injection depending on your business-logic
            bind(User.class).in(Singleton.class); 
            bind(UserController.class).in(Singleton.class);  
          }
        }
    
        public class DefaultErrorMenu extends Menu {
    
          @Inject
          public DefaultErrorMenu(User user, UserController userController) {
            super(user, userController, -1);
          }
        }
    
        public class DefaultSearchMenu extends Menu {
    
          @Inject
          public DefaultSearchMenu(User user, UserController userController) {
            super(user, userController, 0);
          }
        }
    
  • 为您的菜单字段创建自己的注释@SearchMenu@ErrorMenu,并在您的模块中定义它们。

    注释示例:

  • @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD, ElementType.TYPE})
    @BindingAnnotation
    public @interface ErrorMenu {
    }
    

    使用:

    public ErrorView implements View {
    
      @Inject
      @ErrorMenu
      private Menu menu;
    }
    
    或者
    public ErrorView implements View {
    
      private final Menu menu;
    
      @Inject
      public ErrorView(@ErrorMenu Menu menu) {
        this.menu = menu;
      }
    } 
    

    那么就像你定义 @Named("ErrorMenu") 一样来定义注释:

    bind(Menu.class).annotatedWith(ErrorMenu.class).to(DefaultErrorMenu.class);
    

    在某些示例中,我将菜单字段设置为final并删除了对它的setter操作,但如果您确实需要菜单的可变状态,可以将其保持不变。


在 "public class DefaultErrorMenu extends Menu" 中,是否也注入了user和userController? - quarks
在我的控制器类中,我通常有这种模式:XyzController(final Application application, final XyxModel model)。 - quarks
如果user和userController对象满足以下条件,则它们将被注入:1)它们具有无参数的默认构造函数,2)它们具有@Inject注释,并且在您的GinModule类中进行了描述:bind(User.class).somethingelse..... - hsestupin
我不明白这个模式是什么?无论如何,您应该将@Inject注释添加到XyzController类的构造函数中。 - hsestupin
也许你也可以帮我解决这个问题:http://stackoverflow.com/questions/10414089/field-level-injection-with-gin - quarks
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接