es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo validar una anotación personalizada de Programación Orientada a Aspectos (AOP)

Tengo una anotación personalizada de la siguiente manera

@Target (ElementType.METHOD)
@Retention (RetentionPolicy.RUNTIME)
public @interface Testable {
int index ();
}
 

Defino un Aspecto para envolver la llamada real al método.

@Aspect
@Component
public class TestableAspect {

@Around ("execution (public * * (..)) & & @ annotation (anotación)")
public Object invocarYRegistrar(ProceedingJoinPoint joinPoint, Testable annotation) throws Throwable {
    return joinPoint.proceed();
}
}
 

La forma de usar la anotación es la siguiente:

@Testable (índice = 1)
public void metodoReal () {
// algún código aquí
}
 

Esto funciona bien hasta ahora y puedo implementar mi lógica dentro de TestableAspect #invokeAndLog.

Ahora tengo la necesidad de validar que el valor de index no sea mayor que 10, por ejemplo.

Puedo hacer esto en tiempo de ejecución cambiando la implementación del aspecto de la siguiente manera:

@Around ("execution (public * * (..)) & & @ annotation (anotación)")
public Object invocarYRegistrar(ProceedingJoinPoint joinPoint, Testable annotation) throws Throwable {
    if (annotation.index () > 10) {
        throw new IllegalStateException ("blah");
    }
    return joinPoint.proceed();
}
 

Pero esto requiere que la API sea invocada al menos una vez y no es muy eficiente.
¿Hay alguna manera de hacer esto al inicio de la aplicación de Spring Boot?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Sí, puedes usar un BeanPostProcessor para validar los valores de la anotación Testable al inicio de la aplicación Spring Boot.

    Crea una nueva clase llamada TestableAnnotationBeanPostProcessor e implementa la interfaz BeanPostProcessor. Sobrescribe el método postProcessBeforeInitialization para escanear todos los beans en el ApplicationContext y validar los valores de la anotación Testable.

    Aquí tienes un ejemplo de implementación:

    @Component
    public class TestableAnnotationBeanPostProcessor implements BeanPostProcessor {
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            Method[] methods = bean.getClass().getMethods();
            for (Method method : methods) {
                Testable annotation = method.getAnnotation(Testable.class);
                if (annotation != null && annotation.index() > 10) {
                    throw new IllegalArgumentException("Valor inválido para la anotación Testable en el método " + method.getName());
                }
            }
            return bean;
        }
    }
    

    Esta implementación escanea todos los beans en el ApplicationContext y busca métodos con una anotación Testable. Si el valor de index es mayor que 10, se lanza una IllegalArgumentException.

    Ahora, cuando la aplicación Spring Boot se inicie, este BeanPostProcessor será invocado y validará los valores de la anotación Testable para todos los beans en el ApplicationContext. Este enfoque es más eficiente que la implementación original, ya que no requiere que la API se invoque al menos una vez.

Comments are closed.