【问题标题】:How to use Dependency Injection in a ConstraintValidator in Ninjaframework?如何在 Ninjaframework 的 ConstraintValidator 中使用依赖注入?
【发布时间】:2017-10-01 04:42:52
【问题描述】:

我在使用 ninja 框架 (6.0.0-rc1) 和自定义 ConstraintValidator 验证 POST 请求时遇到问题。

这是我当前的实现:

@Singleton public class GameController { public Result postGame(@JSR303Validation final GameRequestObject gameRequestObject, final Validation validation) { if(validation.hasViolations()){ return Results.json().render(validation.getViolations()); } //... code to save game to DB etc ... return Results.ok(); } } public class GameRequestObject { @ValidPlayerId // - Custom validation constraint private long playerId; //... getter, setter etc ... } @Target( { METHOD, FIELD, ANNOTATION_TYPE }) @Retention(RUNTIME) @Constraint(validatedBy = PlayerIdValidator.class) public @interface @ValidPlayerId { String message() default "{ch.some.label.here}"; Class[] groups() default {}; Class[] payload() default {}; } public class PlayerIdValidator implements ConstraintValidator { @Inject // - Does not work private PlayerDao playerDao; // - Is always null public void initialize(ValidPlayerId validPlayerId) {} public boolean isValid(Long value, ConstraintValidatorContext context) { return playerDao != null && playerDao.isPlayerIdValid(value); } }

问题是,playerDao 根本没有被注入。我缩小了问题的范围。似乎调用了默认构造函数而不是使用依赖注入。根据this post,这可以通过使用自定义 ConstraintValidatorFactory 进行更改。

现在我有以下两个问题:

  1. 即使提供了指向休眠文档的链接,我也不知道如何实现这样的工厂以使 DI 正常工作。
  2. 在 ninja 框架中的哪里注册/绑定/(“随便”)我的工厂?

【问题讨论】:

    标签: java dependency-injection guice ninjaframework


    【解决方案1】:

    由于您的 PlayerIdValidator 未使用 guice 实例化,您将无法在该类中启用依赖注入。您可以使用使用注射器的替代解决方案。

    要存储您的注入器引用,您可以使用单例 - 这里我使用枚举来实现它:

    public enum InjectorProvider {
      INSTANCE;
      private Injector injector;
      public Injector getInjector() {
        return injector;
      }
      public void setInjector(Injector injector) {
        this.injector = injector;
      }      
    }
    

    我不知道你是怎么初始化guice的,但是你可能有一些这样的代码,所以添加代码来存储注入器:

    Injector injector = Guice.createInjector(...your modules...);
    InjectorProvider.INSTANCE.setInjector(injector);
    

    现在使用这个提供程序来获取注入器并实例化 PlayerDao:

    public boolean isValid(Long value, ConstraintValidatorContext context) {
        Injector injector = InjectorProvider.INSTANCE.getInjector();
        PlayerDao playerDao = injector.getInstance(PlayerDao.class);
        return playerDao != null && playerDao.isPlayerIdValid(value);
    }
    

    【讨论】:

    • 感谢您的回答。我以前看过这段代码,但我现在不知道在我的代码中将Injector injector = Guice.createInjector(...your modules...); 放在哪里。另外:我还没有任何模块。我拥有的唯一模块是由 ninja 原型 (conf/Module.java) 生成的,目前是空的。
    • 您的项目是否包含 web.xml?如果是,您可以创建 GuiceServletContextListener 来创建注入器。
    • 我最终创建了一个忍者开始动作@Start(order = 91) public void configureInjector() { InjectorProvider.INSTANCE.setInjector(injector); }。现在一切正常。感谢您的意见。
    猜你喜欢
    • 2013-06-09
    • 1970-01-01
    • 2022-07-07
    • 1970-01-01
    • 1970-01-01
    • 2013-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多