如何在Ninjaframework中的ConstraintValidator中使用Dependecy Injection?

时间:2017-05-03 11:18:00

标签: java dependency-injection guice ninjaframework

我在使用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);
        }

    }


问题是,玩家道才完全没注射。我缩小了问题范围。似乎调用默认构造函数而不是使用Dependecy Injection。根据{{​​3}},可以使用自定义ConstraintValidatorFactory更改此值。

现在我有以下两个问题:

  1. 即使提供了hibernate文档的链接,我也不知道如何实现这样的工厂,以便DI工作。
  2. 我在ninja框架中注册/绑定/("无论什么")我的工厂在哪里?

1 个答案:

答案 0 :(得分:2)

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

要存储您的注射器参考,您可以使用Singleton - 我在这里使用枚举实现它:

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);
}