Spring - перехватывает создание бина и вводит собственный прокси
у меня есть@Controller
с участием@Autowired
поля и методы-обработчики, которые я хочу аннотировать с помощью пользовательских аннотаций.
Например,
@Controller
public class MyController{
@Autowired
public MyDao myDao;
@RequestMapping("/home")
@OnlyIfXYZ
public String onlyForXYZ() {
// do something
return "xyz";
}
}
где@OnlyIfXYZ
пример пользовательской аннотации Я думал, что перехватлю создание bean-компонента Controller, передам свой собственный прокси-сервер CGLIB, в котором Spring может затем установить свойства, например, поле autowired.
Я пытался с помощью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;
}
}
Это решение использует отражение, чтобы скопировать все поля целевого компонента в прокси-компонент (что-то вроде хакерства на мой вкус). Но у меня нет доступа кHttpServletRequest
а такжеHttpServletResponse
объекты, если это не аргументы в методе, который я перехватываю.
Есть ли другой обратный вызов, который я могу внедрить в логику создания bean-компонента Spring, чтобы добавить мой собственный прокси-контроллер, прежде чем Spring заполнил его свойства?Мне нужно иметь доступ кHttpServletRequest
а такжеHttpServletResponse
объекты независимо от того, имеет ли метод-обработчик его в своем определении, т.е. в качестве аргументов.
N.B @Autowired
поле также является прокси, оно помечено@Transactional
так что Spring это прокси
РЕДАКТИРОВАТЬ: Решение AOP прекрасно работает для перехвата вызова метода, но я не могу найти способ доступа кHttpServletRequest
а такжеHttpServletResponse
объекты, если они еще не являются аргументами метода.
Я, вероятно, собираюсь в конечном итоге использовать HandlerInterceptorAdapter, но я надеялся, что смогу сделать это с ООП, чтобы не добавлять накладные расходы к методам, которые в этом не нуждаются.