Java Dropwizard инициализирует ConstraintValidator

Скажем, у меня есть собственный ConstraintValidator:

public class FooValidator implements ConstraintValidator<ValidFoo, String> {
    @Override
    public void initialize(final ValidFoo foo) {
        // No-op
    }

    @Override
    public boolean isValid(final String foo, final ConstraintValidatorContext context) {

    }
}

Я хотел бы иметь возможность инициализировать этот класс, передав некоторую конфигурацию из ServiceConfiguration в Dropwizard run или initialize.

Это возможно?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
480
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Во-первых, стоит отметить, что в предстоящем выпуске Dropwizard 2.0.0 есть встроенный в поддержку этого


На данный момент процесс немного сложен. Вы в основном хотите повторно запустить проверку Hibernate, но с настраиваемой фабрикой валидатора ограничений, которая будет поддерживать инъекцию.

В нем будет задействовано около 4 пользовательских классов, так что терпите меня. Поехали:

Во-первых, мы начинаем с регистрации настраиваемой функции для обертывания этой функции в нашем классе Application:

public void run(MainConfiguration config, Environment environment) throws Exception {
  // ...
  environment.jersey().register(InjectingValidationFeature.class);
}

Теперь мы определяем функцию: InjectingValidationFeature - она ​​в основном регистрирует наши пользовательские реализации в сервисном контейнере:

public class InjectingValidationFeature implements Feature {

  @Override
  public boolean configure(FeatureContext context) {
    context.register(new AbstractBinder() {
      @Override
      protected void configure() {
        bindFactory(ValidatorFactory.class).to(Validator.class).in(Singleton.class);
        bind(InjectingConfiguredValidator.class).to(ConfiguredValidator.class).in(Singleton.class);
        bind(InjectingConstraintValidatorFactory.class).to(ConstraintValidatorFactory.class).in(Singleton.class);
      }
    });

    return true;
  }
}

Теперь мы определяем те классы, которые мы регистрируем выше. Начнем с основной части, InjectingConstraintValidatorFactory, которую Hibernate Validator фактически будет использовать для создания валидаторов ограничений. Обратите внимание, что, поскольку мы регистрируем их в контейнере, мы уже можем начать вводить данные, вот наш собственный ConstraintValidatorFactory, использующий локатор служб, чтобы сделать возможной инъекцию зависимостей:

public class InjectingConstraintValidatorFactory implements ConstraintValidatorFactory {

  private final ServiceLocator serviceLocator;

  @Inject
  public InjectingConstraintValidatorFactory(ServiceLocator serviceLocator) {
    this.serviceLocator = serviceLocator;
  }

  @Override
  public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) {
    return this.serviceLocator.createAndInitialize(key);
  }

  @Override
  public void releaseInstance(ConstraintValidator<?, ?> instance) {
    this.serviceLocator.preDestroy(instance);
  }
}

Теперь наша фабрика для центрального интерфейса javax.validation.Validator:

public class ValidatorFactory implements Factory<Validator> {

  private final ConstraintValidatorFactory constraintValidatorFactory;

  @Inject
  public ValidatorFactory(ConstraintValidatorFactory constraintValidatorFactory) {
    this.constraintValidatorFactory = constraintValidatorFactory;
  }

  @Override
  public Validator provide() {
    return Validation.byDefaultProvider().configure().constraintValidatorFactory(
        this.constraintValidatorFactory).buildValidatorFactory()
        .getValidator();
  }

  @Override
  public void dispose(Validator instance) {
    // Nothing
  }
}

И, наконец, наш InjectingConfiguredValidator, обратите внимание, как он просто использует DropwizardConfiguredValidator, но с @Inject, который позволит нам получать валидатор от нашего ValidatorFactory, приведенного выше:

public class InjectingConfiguredValidator extends DropwizardConfiguredValidator {
  @Inject
  public InjectingConfiguredValidator(Validator validator) {
    super(validator);
  }
}

Вот и все. Благодаря вышесказанному нам удалось зарегистрировать Validator с поддержкой инъекций в Jersey, а также в нашем сервисном контейнере, так что вы также можете @Inject Validator где угодно и использовать его, как вам нравится.

Другие вопросы по теме