Проверьте аргументы для всех аннотированных методов во время выполнения

#java #spring #annotations #aspectj #interceptor

#java #весна #аннотации #aspectj #перехватчик

Вопрос:

Как вы можете выполнить проверку во время запуска во всех вариантах использования аннотации?

Например, у меня есть этот аспект, который применяется к аннотированным методам @Protect , который применяет некоторую политику безопасности. Во всей системе у нас есть методы, аннотированные с @Protect("valid-operation-1") помощью , @Protect("valid-operation-2") или @Protect("INVALID-operation") . Как только приложение запустится, я хотел бы проверить аргументы, предоставленные для всех этих аннотаций, чтобы обнаружить такие неправильные настройки.

В частности, я проверю, что у нас есть компонент, определенный в контексте приложения Spring, идентификатор которого соответствует аргументу аннотации. Это означает, что для защиты метода void drive() я буду аннотировать с @Protect("drive") помощью, и ожидать, что компонент protect_drive будет присутствовать в контексте приложения.

Вы можете легко просто подождать, пока метод не будет вызван, затем будет вызван совет, и вы проверите аргумент. Затем вы увидите, что INVALID-operation это неверно определено. Но это слишком поздно.

Возможно ли проверить это для всех аннотированных методов при запуске приложения?

Комментарии:

1. Это потребует от вас загрузки всех этих классов при запуске. Допустимо ли влияние на время запуска?

2. Можете ли вы дать некоторое представление о природе строк «operation»? Какой контроль у вас есть над ними? Могут ли они быть ограничены, скажем, допустимыми именами Java (без тире и др.)? Существует ли их набор, который действителен во всем мире в системе? Может ли этот набор быть скомпилирован как перечисление, а затем использовать значения перечисления в вашем @Protect? И т.д…

3. Ed, я обновил вопрос с разъяснением аргументов аннотаций. У меня нет контроля над ними. Время запуска может занять много времени, это не будет проблемой. Но вы поднимаете интересный момент. С другой стороны, вы можете получить доступ к выражению pointcut и выполнить тот же поиск, что и движок AspectJ, что, я полагаю, довольно недорого.

Ответ №1:

Если классы, которые вы хотите проверить, являются Spring Beans, вы можете использовать BeanPostProcessor .

 public class OnlyAScratchForAnPostProcessor {

    @Inject
    private ApplicationContext context;


    @Override
    public Object postProcessAfterInitialization(final Object bean,
        final String beanName) throws BeansException {

          ReflectionUtils.doWithMethods(bean.getClass(), new MethodCallback() {

             @Override
             public void doWith(Method method) throws IllegalArgumentException,
                         IllegalAccessException {

                  String expecedNameFromAnnotation = scanAnnotation(method);
                  if(expecedNameFromAnnotation != null) {
                      if(context.beanByName(expecedNameFromAnnotation) != null) {
                         throw new RuntimeException("illegal configuration");
                      }
                  }         
             }

             String scanAnnotation(Method method){...}

          }, ReflectionUtils.USER_DECLARED_METHODS);        

    }