У меня есть поля @Controller
с @Autowired
и методы обработчика, которые я хочу аннотировать с помощью специальных аннотаций.
Например,
@Controller
public class MyController{
@Autowired
public MyDao myDao;
@RequestMapping("/home")
@OnlyIfXYZ
public String onlyForXYZ() {
// do something
return "xyz";
}
}
Где @OnlyIfXYZ
- пример пользовательской аннотации. Я думал, что перехватил создание Controller bean, передал свой собственный прокси CGLIB, на котором Spring может затем установить свойства, такие как поле с автоопределением.
Я попробовал использовать InstantiationAwareBeanPostProcessor
, но это решение не работает отлично, потому что postProcessBeforeInstantiation()
замыкает всю оставшуюся часть процесса. Я попытался с postProcessAfterInitialization()
, как показано ниже
public class MyProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// Here the bean autowired fields are already set
return bean;
}
@Override
public Object postProcessAfterInitialization(Object aBean, String aBeanName) throws BeansException {
Class<?> clazz = aBean.getClass();
// only for Controllers, possibly only those with my custom annotation on them
if (!clazz.isAnnotationPresent(Controller.class))
return aBean;
Object proxy = Enhancer.create(clazz, new MyMethodInterceptor());
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
try {
// get the field and copy it over to the proxy
Object objectToCopy = field.get(aBean);
field.set(proxy, objectToCopy);
} catch (IllegalArgumentException | IllegalAccessException e) {
return aBean;
}
}
return proxy;
}
}
Это решение использует отражение для копирования по всем полям целевого bean в прокси bean (вроде хаки для моего вкуса). Но у меня нет доступа к объектам HttpServletRequest
и HttpServletResponse
, если они не являются аргументами в методе, который я перехватываю.
Есть ли еще один обратный вызов, который я могу ввести в логику создания Spring bean для ввода моего собственного прокси-контроллера до того, как Spring заполнит его свойства? Мне нужно иметь доступ к объектам HttpServletRequest
и HttpServletResponse
независимо от того, имеет ли метод обработчика контроллера его определение, т.е. как аргументы.
N.B Поле @Autowired
также является прокси, оно аннотируется с помощью @Transactional
, поэтому Spring проксирует его.
EDIT: Решение AOP прекрасно работает для перехвата вызова метода, но я не могу найти способ доступа к объектам HttpServletRequest
и HttpServletResponse
, если они еще не являются методами аргументы.
Возможно, мне удастся использовать HandlerInterceptorAdapter, но я надеялся, что смогу сделать это с помощью ООП, чтобы не добавлять накладные расходы к методам, которые ему не нужны.