当前位置: 首页 > 知识库问答 >
问题:

自动装配的HTTPServletRequest bean的Spring AOP和方面线程安全

梁丘烨
2023-03-14

我使用的是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线程是否安全?如果不是,那么在建议执行期间获取它并使其成为线程安全的最佳方法是什么?如果可能的话,我宁愿不使用本地线程。

共有1个答案

呼延宪
2023-03-14

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

每个bean实例调用一次。如果bean有一个单例作用域(这也是方面的默认情况),那么它将只被调用一次。但是,您将无法访问httpServletRequest内部的init()方法-目前还没有请求!

httpServletRequest线程安全吗

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

整个行为在4.5.4.5范围bean中作为依赖项进行了详细描述:

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

关于ThreadLocal:

我不喜欢使用本地线程。

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

 类似资料:
  • 问题内容: 我有以下spring配置: 然后我有一个方面: 此方面有效(我可以在afterPoll上达到断点),但是simpleEmailSender为null。不幸的是,我找不到清楚的文档说明为什么这样做。(作为记录,我的simpleEmailSender bean存在并且已正确连接到其他类中)以下几点使我感到困惑: 是context:component-scan应该是@Aspect吗?如果可以

  • 问题内容: 我有以下弹簧配置: 然后我有一个方面: 此方面有效(我可以在afterPoll上达到断点),但是simpleEmailSender为null。不幸的是,我找不到明确的文档说明为什么这样做。(作为记录,我的simpleEmailSender bean存在并且已正确连接到其他类中)以下几点使我感到困惑: 是否应该使用context:component-scan获取@Aspect?如果可以肯

  • 本文向大家介绍Spring的自动装配Bean的三种方式,包括了Spring的自动装配Bean的三种方式的使用技巧和注意事项,需要的朋友参考一下 spring的自动装配功能的定义:无须在Spring配置文件中描述javaBean之间的依赖关系(如配置<property>、<constructor-arg>)。IOC容器会自动建立javabean之间的关联关系。 如果没有采用自动装配的话,手动装配我们

  • 本文向大家介绍mysql一键安装教程 mysql5.1.45全自动安装(编译安装),包括了mysql一键安装教程 mysql5.1.45全自动安装(编译安装)的使用技巧和注意事项,需要的朋友参考一下 一.问题来源  安装MySQL如果手动安装一台还可以,但安装多台,手动安装很麻烦,需要编写一个shell程序 install_mysql.sh来进行安装 二.程序说明  将MySQL5.1.45安装到

  • 主要内容:读者,前提条件,Spring AOP 概述Spring框架的关键组件之一是面向方面编程(AOP)框架。 面向方面的编程需要将程序逻辑分解成不同的部分。 此教程将通过简单实用的方法来学习Spring框架提供的AOP/面向方面编程。 读者 本教程主要是为Spring 面向方面编程(AOP)初学者准备的,帮助他们了解与Spring的AOP框架相关的基础到高级概念。 前提条件 在开始练习本教程系列文章中给出的各种类型的示例之前,我们假设您已经了解

  • 问题内容: 我在两个不同的线程之间使用。一个线程通过添加数据,而另一个线程通过添加数据。 我的问题是,我是否需要同步对和的访问。是的插入和删除方法是线程安全的? 问题答案: 是。从文档: “ BlockingQueue实现是线程安全的。所有排队方法都使用内部锁或其他形式的并发控制以原子方式实现其效果。但是,除非在实现中另行指定,否则批量Collection操作addAll,containsAll,