I am using Spring 3 AOP, and I have an aspect that requires access to the HttpServletRequest. It looks something like this:
@Aspect
public class MyAspect {
@Autowired
private HttpServletRequest httpServletRequest;
public void init() {
// Do something once...
}
@Before("my pointcut here...")
private void myMethod() {
// I need the httpServletRequest...
}
@After("my pointcut here...")
private void myOtherMethod() {
// I need the httpServletRequest...
}
}
And is configured like this:
<bean id="myAspect" class="com.some.package.MyAspect" init-method="init" />
Is the init method only called once per IoC container, even though this is an aspect, and is the httpServletRequest thread safe? If it is not, what is the best way to get at it during execution of the advice and have it be thread safe? If at all possible I prefer not to use a thread local.
It is called once per every bean instance. If bean has a singleton scope (which is the default case for aspects as well), it will only be called once. However you won’t have access to the
httpServletRequestinsideinit()method – there is no request yet!It is not but don’t worry. This is actually much more complex than it looks like. You are injecting HTTP servlet request (and obviously there can be several requests available at the same time) into a singleton object. Which one is injected? None (all?) of them! Spring creates some sophisticated proxy (called scoped proxy) and every time you access methods of injected
httpServletRequestit delegates them to current (to thread) request. This way you can safely run your aspects in several threads – each will operate on a different physical request.This whole behaviour is described in great details in 4.5.4.5 Scoped beans as dependencies:
About
ThreadLocal:Fortunately – Spring is using one for you. If you understand how
ThreadLocalworks – Spring puts current request into a thread local and delegates to thread-local instance when you accesshttpServletRequestproxy.