#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);
}