有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何在Ninjaframework中的ConstraintValidator中使用依赖项注入?

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

    }


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

现在我有以下两个问题:

  1. 即使提供了hibernate文档的链接,我也不知道如何实现这样一个工厂,从而使DI正常工作
  2. 在忍者框架中,我在哪里注册/绑定我的工厂

共 (1) 个答案

  1. # 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);
    

    现在使用此提供程序获取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);
    }