Spring - 拦截豆子创建和注入自定义代理
我有一个带有字段和处理程序的方法,我想用自定义批注进行批注。@Controller
@Autowired
例如
@Controller
public class MyController{
@Autowired
public MyDao myDao;
@RequestMapping("/home")
@OnlyIfXYZ
public String onlyForXYZ() {
// do something
return "xyz";
}
}
其中 是自定义批注的示例。我想我会拦截控制器bean的创建,传递我自己的CGLIB代理,然后Spring可以在其上设置属性,例如自动连接字段。@OnlyIfXYZ
我尝试使用一个,但该解决方案效果不佳,因为该过程的其余部分短路。我试过,如下所示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(对于我的口味来说有点黑客)。但是,如果 and 对象不是我正在截取的方法中的参数,则我无法访问 and 对象。HttpServletRequest
HttpServletResponse
在Spring填充其属性之前,是否可以将另一个回调注入Spring Bean创建逻辑以注入我自己的代理控制器?我需要能够访问 HttpServletRequest
和 HttpServletResponse
对象,而不管 Controller handler 方法是否在其定义中包含它,即作为参数。
注意:该字段也是一个代理,它被注释为Spring代理它。@Autowired
@Transactional
编辑:AOP解决方案非常适合拦截方法调用,但是如果它们不是方法参数,我找不到访问和对象的方法。HttpServletRequest
HttpServletResponse
我可能最终会使用HandlerInterceptorAdapter,但我希望我能用OOP做到这一点,这样就不会给不需要它的方法增加开销。