Похожие вопросы, но ответов на них так и не последовало, возможно сейчас сюда забредет гуру спринга и разложит все по полочкам: тыц и тыц
Суть проблемы: пишу свой BeanPostProcessor (BPP) для "логгирования" классов, которые помечены моей аннотацией. Соответственно, если класс помечен данной аннотацией, то пускаем его через прокси и пишем логику необходимую. Однако, если класс был помечен другими аннотациями (например @Controller), то Proxy это все дело игнорирует и на выходе мы получаем логгирующийся класс, но без всех остальных наворотов.
Вопрос: Каким способом можно реализовать BPP и проксировать в нем классы так, чтобы другая логика, связанная с аннотациями не терялась? Или же можно обойтись как нибудь без прокси (но с BPP). (Аспекты не предлагать, вопрос именно в BPP).
UPD: Как один из вариантов решения данной проблемы - объявлять бины не с помощью аннотаций. Но это ограничения, которые нежелательны. Так же будут "заигнорены" другие аннотации, кроме "пользовательской, по которой создается прокси.
Надеюсь мой ответ не слишком поздно для тебя
У меня есть подозрение, что ты не правильно создаешь прокси
У меня была похожая задача, мне было необходимо логировать реквест и респонс контроллеров, если на методе была повешена моя аннотация @Logging
Реализация моей задачи выглядит следующим образом. Аннотация с двумя параметрами, для гибкой настройки логирования реквеста и респонса (мне не всегда необходимо логировать респонс):
@Inherited
@Documented
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Logging {
boolean isRequest() default true;
boolean isResponse() default true;
}
БинПостПроцессор выглядит следующим образом. Для создания динамическим прокси на лету, я использовал CGLIB, т.к. она работает быстрее стандартных инструментов JDK:
@Slf4j
@Component
public class LoggingBeanPostProcessor implements BeanPostProcessor {
private Map<String, Class> loggingBeans = new HashMap<>();
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
Class<?> beanClass = bean.getClass();
if (Arrays.stream(beanClass.getMethods()).anyMatch(method -> method.isAnnotationPresent(Logging.class))) {
loggingBeans.put(beanName, beanClass);
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
Class originalBean = loggingBeans.get(beanName);
if (originalBean != null) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(originalBean);
enhancer.setCallback((MethodInterceptor) (obj, method, args, proxy) -> {
Optional<Method> originalMethod = Arrays.stream(originalBean.getMethods())
.filter(method::equals)
.findFirst();
if (originalMethod.isPresent()) {
Logging annotation = originalMethod.get().getAnnotation(Logging.class);
if (annotation != null) {
if (annotation.isRequest()) {
log.info("{}#{}: {}", originalBean.getSimpleName(), method.getName(), Arrays.asList(args).toString());
}
Object invoke = proxy.invoke(bean, args);
if (annotation.isRequest()) {
log.info("{}#{}: {}", originalBean.getSimpleName(), method.getName(), invoke != null ? invoke.toString() : "void");
}
return invoke;
}
}
return method.invoke(bean, args);
});
return enhancer.create();
}
return bean;
}
}
Кусок кода с использованием аннотации из контроллера:
@GetMapping("/type")
@Logging(isResponse = false)
public Object getTypes() {
//мясо метода
}
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Несколько дней назад сайт перевели на https, и сайт перестал парситьсяДругие https сайты парсятся без проблем
Суть проблемы: пишу тесты для дао слоя и не при запуске вылазит ошибка failed to load applicationcontextПомогите, кто знает в чем проблема
Раньше по двойному клику открывалось gui приложение на OpenJDK Java 8 Policy ToolНе знаю что случилось, но стало запускаться только из консоли