Note that there are some explanatory texts on larger screens.

plurals
  1. POSpring - Intercepting bean creation and injecting custom proxy
    text
    copied!<p>I have a <code>@Controller</code> with <code>@Autowired</code> fields and handler methods that I want to annotate with custom annotations. </p> <p>For example,</p> <pre><code>@Controller public class MyController{ @Autowired public MyDao myDao; @RequestMapping("/home") @OnlyIfXYZ public String onlyForXYZ() { // do something return "xyz"; } } </code></pre> <p>Where <code>@OnlyIfXYZ</code> is an example of a custom annotation. I was thinking I would intercept the Controller bean creation, pass my own CGLIB proxy on which Spring can then set properties, like the autowired field.</p> <p>I tried using a <code>InstantiationAwareBeanPostProcessor</code> but that solution doesn't work great because <code>postProcessBeforeInstantiation()</code> short-circuits the rest of the process. I tried with <code>postProcessAfterInitialization()</code>, like below</p> <pre><code>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&lt;?&gt; 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; } } </code></pre> <p>This solution uses reflection to copy over all the fields of the target bean to the proxy bean (kind of hacky for my taste). But I don't have access to the <code>HttpServletRequest</code> and <code>HttpServletResponse</code> objects if those aren't arguments in the method I'm intercepting.</p> <p>Is there another callback I can inject into Spring bean creation logic to inject my own Proxy Controller before Spring populates its properties? <strong>I need to be able to access the <code>HttpServletRequest</code> and <code>HttpServletResponse</code> objects regardless of if the Controller handler method has it in its definition, ie. as arguments.</strong></p> <p><strong>N.B</strong> The <code>@Autowired</code> field is also a proxy, it is annotated with <code>@Transactional</code> so Spring proxies it up.</p> <p><strong>EDIT:</strong> The AOP solution works nicely for intercepting the method invocation, but I can't find a way to access the <code>HttpServletRequest</code> and <code>HttpServletResponse</code> objects, if they aren't already method arguments.</p> <p>I'm probably going to end up using HandlerInterceptorAdapter, but I was hoping I can do it with OOP so as to not add the overhead to methods that don't need it.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload