自动连接的HTTPServletRequest bean的Spring AOP和方面线程安全性 [英] Spring AOP and aspect thread safety for an autowired HTTPServletRequest bean
问题描述
我正在使用Spring 3 AOP,并且我有一个方面需要访问HttpServletRequest.看起来像这样:
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...
}
}
并且配置如下:
<bean id="myAspect" class="com.some.package.MyAspect" init-method="init" />
即使这是一个方面,init方法在每个IoC容器中仅被调用一次,并且httpServletRequest线程安全吗?如果不是,那么在执行建议期间获取建议并使其具有线程安全性的最佳方法是什么?如果可能的话,我宁愿不要使用本地线程.
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.
推荐答案
每个IoC容器仅调用一次init方法
Is the init method only called once per IoC container
每个init()
方法中的httpServletRequest
-尚无请求!
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 httpServletRequest
inside init()
method - there is no request yet!
httpServletRequest线程是否安全
is the httpServletRequest thread safe
不是,但是不用担心.这实际上比看起来要复杂得多.您正在将HTTP servlet请求(显然可以同时有多个请求)注入到一个singleton对象中.注入哪一个?没有一个(全部?)! Spring创建了一些复杂的代理(称为 scoped代理),每次您访问注入的httpServletRequest
方法时,它将它们委托给 current (线程)请求.这样,您可以在多个线程中安全地运行方面-每个方面都将在不同的物理请求上运行.
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 httpServletRequest
it 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.