【问题标题】:Spring AOP and aspect thread safety for an autowired HTTPServletRequest bean自动装配的 HTTPServletRequest bean 的 Spring AOP 和方面线程安全
【发布时间】:2013-06-08 23:38:51
【问题描述】:

我正在使用 Spring 3 AOP,并且我有一个方面需要访问 HttpServletRequest。它看起来像这样:

@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" />

每个 IoC 容器是否只调用一次 init 方法,即使这是一个方面,并且 httpServletRequest 线程是否安全?如果不是,那么在执行建议期间获取它并使其成为线程安全的最佳方法是什么?如果可能的话,我宁愿不使用本地线程。

【问题讨论】:

    标签: spring servlets thread-safety aop spring-aop


    【解决方案1】:

    每个 IoC 容器是否只调用一次 init 方法

    每个 bean 实例调用一次。如果 bean 有一个单例范围(这也是方面的默认情况),它只会被调用一次。但是,您将无法访问 init() 方法中的 httpServletRequest - 还没有请求!

    httpServletRequest 线程是否安全

    不是,但不要担心。这实际上比看起来要复杂得多。您正在将 HTTP servlet 请求(显然可以同时有多个请求)注入到单例对象中。注入哪一个?一个都没有(全部?)! Spring 创建了一些复杂的代理(称为作用域代理),每次您访问注入的httpServletRequest 方法时,它都会将它们委托给当前(到线程)请求。通过这种方式,您可以安全地在多个线程中运行方面 - 每个线程都将针对不同的物理请求进行操作。

    4.5.4.5 Scoped beans as dependencies 中详细描述了整个行为:

    [...] 如果你想将一个 HTTP 请求范围的 bean 注入(例如)另一个 bean,你必须注入一个 AOP 代理来代替这个范围的 bean。也就是说,您需要注入一个代理对象,该对象公开与作用域对象相同的公共接口,但也可以从相关作用域(例如,HTTP 请求)检索真实的目标对象,并将方法调用委托给真实对象.

    关于ThreadLocal

    我不喜欢使用本地线程。

    幸运的是 - Spring 正在为您使用一个。如果您了解 ThreadLocal 的工作原理 - Spring 将当前请求放入本地线程并在您访问 httpServletRequest 代理时委托给线程本地实例。

    【讨论】:

    • 汤姆,这是一个很好的答案。 Spring 是否有可能将其记录在我可以阅读的某个地方?很难找到与代理实际工作方式相关的任何内容。哦,我不需要从 init() 中访问请求——那是我作弊并将两个问题合并为一个 :)
    • @BrianReindel:我在回答中引用了 Spring 文档。
    • 嗨 Thomasz,答案中的代码可以工作吗?能否也对“stackoverflow.com/questions/22923813/…”发表意见
    猜你喜欢
    • 1970-01-01
    • 2016-06-03
    • 2012-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多