Tengo un problema con el autoenvío de beans dentro de un validador de restricciones personalizado. No se proporciona una instancia de validador de restricción utilizando LocalValidatorFactoryBean de Spring. El proveedor JSR-303 es hibernate-validator 4.2.0.Final. configuraciónSpring 3.1 El autoenrutamiento no funciona dentro del validador de restricciones personalizado
primavera extracto:
<!-- JSR 303 validation -->
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/>
Custom Constraint Validador:
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import org.springframework.beans.factory.annotation.Autowired;
import com.model.Subject;
import com.services.SomeTypeService;
public class ReadOnlyValidator implements ConstraintValidator<ReadOnly, String> {
@Autowired
private SomeTypeService someTypeService;
@Override
public void initialize(ReadOnly constraintAnnotation) { }
@Override
public boolean isValid(String type, ConstraintValidatorContext context) {
try {
if (null != type) {
return !someTypeService.isReadonly(type);
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
Anotación:
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
@Constraint(validatedBy = ReadOnlyValidator.class)
@Documented
public @interface ReadOnly {
String message() default "{constraints.subjecttype.readonly}";
public abstract Class<?>[] groups() default {};
public abstract Class<? extends Payload>[] payload() default {};
}
SomeService:
@Validated
public interface SomeService {
...
public void updateType(@ReadOnly String type) throws SomeException;
...
}
SomeServiceImpl:
@Service
public class SomeServiceImpl implements SomeService {
...
public void updateType(String type) throws SomeException {
// do something
}
...
}
SomeTypeService es otro Bean anotado @Service que no depende de SomeService ...
El problema es que me sale un NPE como autowiring no funciona; alguien más está administrando las instancias personalizadas del validador y no Spring ...
Gracias de antemano por cualquier tipo de asesoramiento.
Pregunta Claudiu: ¿Tiene dos contextos de aplicación diferentes, uno declarado a través de ContextLoaderListener y otro a través de DispatcherServlet, ya que se ha validado a nivel de métodos de servicio, probablemente también deba declarar LocalValidatorFactoryBean en el contexto de la aplicación web raíz? –
Bueno, encontré algunas anomalías relacionadas con el número de instancias de LocalValidatorFactoryBean. La declaración que di en la descripción de la "pregunta" se encuentra en un servicio-contenido.xml => esta es una instancia. Hay otra instancia creada automáticamente al usar => usted tiene razón acerca de tener una aplicación web raíz. –
Después de verificar que solo se creó una instancia de LocalValidatorFactoryBean, me he movido para verificar también cuántas instancias de ReadOnlyValidator se crearon. Usando jmap -histo: live | grep "ReadOnlyValidator", me he dado cuenta de que solo se crea una instancia, pero solo cuando se llama al método de servicio updateType por primera vez y no cuando se inicializa LocalValidatorFactBean.Creo que el motor de validación de hibernación simplemente crea su propia instancia de validación de restricciones. ¿Cómo podría "forzar" a LocalValidatorFactoryBean a administrar la instancia de ReadOnlyValidator para que se pueda usar el cableado de bean? –