当前位置: 首页 > 面试题库 >

Struts2线程中的拦截器是否不安全?

有玄天
2023-03-14
问题内容

我知道Struts2
Action类是线程安全的,因为这些操作放在了值堆栈中。值堆栈又是动作上下文的一部分。由于操作上下文是线程本地的,因此存储在操作上下文中的值(包括值堆栈)在每个线程中都是唯一的。因此,动作是线程安全的。

但是考虑一下拦截器:它们确实很有用,它们为程序员完成了所有繁琐的小工作……例如验证,获取参数值等。但是要考虑的是:拦截器可以在多个请求之间共享。那么这会使拦截器线程不安全吗?

考虑到这个问题,我试图在网上冲浪一些与此问题相关的好文章。我找到了一篇很好的文章,在其中清楚地提到了一个示例,说明拦截器不是线程安全的。

该网页是:http : //www.bullraider.com/java/struts2/tutorials/interceptors-
and-thread-
safety

我从本文了解到的是,拦截器线程不安全的主要原因是拦截器仅创建一次。即每个拦截器只有一个对象。因此,当线程之间共享一个Interceptor 的 相同实例
时,实例字段并不安全。

在文章的结尾提到了在某些情况下,甚至拦截器也是线程安全的。但是他们没有提到任何这样的情况。我在网上冲浪找到答案…但是徒劳地:(

谁能告诉我或提供一个链接,让我找到如何使拦截器成为线程安全的(或拦截器是线程安全的情况是什么)?


问题答案:

任何 不使用 实例字段或其他共享状态的拦截器都是线程安全的:

例如,查看所有解析HTTP请求参数和cookie,进行日志记录,访问检查,异常处理的内置拦截器:它们不将实例字段用于可变状态(*),而是仅对ActionInvocation它们作为参数获取的实例进行操作。

(*)确实有一些配置参数的实例字段,这些实例字段是在Struts启动时(在单个线程中)设置的,例如ExceptionMappingInterceptor或线程安全实例字段(例如Loggerin)LoggingInterceptor

如果您打算自己编写代码Interceptor,则只使用ActionInvocation您传入的参数和intercept()方法中的局部变量即可。避免使用诱人的拦截方法synchronized或将事情放到synchronized{}块中的诱惑-
这将使Struts的Interceptor的单实例方法产生瓶颈。

要回答评论中的问题:

(1)为每个线程创建一个动作实例怎么不影响性能?

使用现代JVM,创建对象的成本可以忽略不计。如果通过避免昂贵的初始化操作(例如,不在操作内部创建数据库连接而是使用连接池)来保持操作轻巧,则对性能不会有明显影响。

(2)您是否建议不要使用默认的拦截器堆栈,并且始终使用自定义拦截器堆栈(将使用实例变量的所有未使用的拦截器都删除),以确保线程安全?

我认为Struts 2附带并配置的默认拦截器都不是线程安全的。即使它们使用实例字段(因为它们要么仅用于配置,要么本身像一样是线程安全的Logger)。

根据我的个人经验,只有在有充分理由(内置拦截器的线程安全性不是一个)的情况下,才应接触/更改拦截器堆栈。如果更改堆栈,很多事情都会以意外的方式表现/破坏-
运行诸如“ default”或“
paramPrepareParam”之类的内置堆栈,从长远来看可以节省很多挫败感。与从现有堆栈中删除/重新排列拦截器相比,添加您自己的自定义拦截器通常不会造成破坏。



 类似资料:
  • 主要内容:Struts2框架的拦截器:,如何使用拦截器?,创建自定义的拦截器,创建拦截器类:,创建动作类:,创建视图,创建页面:,配置文件,堆叠多个拦截器:拦截器的概念是Servlet过滤器或JDK代理类一样的。拦截器允许横切功能分开实现的动作,以及框架。使用拦截器,可以实现如下: 提供预处理行动之前被称为逻辑。 提供后处理逻辑动作后被调用 捕获异常,这样可以进行替代处理。 Struts2框架提供的许多功能都使用拦截实现的例子包括异常处理,文件上传,生命周期回调和验证等事实上作为Struts2的

  • 主要内容:参考很多时候,相同的一组拦截器可以适用于不同的动作类,例如, 在上述情况下,它有许多重复工作以及不能重复使用。 幸运的是,在Struts 2自带的拦截器栈,使开发人员建立一组拦截到一个单元名为“栈名字”, 和可以通过“栈名字”引用操作它。 最佳做法 建议组合相同的一组拦截器到一个拦截器栈摆脱重复的工作,并增加了项目的可重用性。 在上面的例子更新,声明一个拦截器栈,命名为“defaultStackWit

  • 主要内容:1. 动作,2. JSP页面,3. 执行和等待拦截器,4. 示例,参考在Struts2中附带一个名为“execAndWait”一个非常有趣的“执行和等待”拦截器,这是一个非常方便的拦截器长时间运行操作在后台,显示用户的自定义的等待页面。在本教程中,它显示了一个完整的使用 Struts2 execAndWait 拦截器的例子。 1. 动作 一个普通的动作类,有一个长时间运行进程,证明了execAndWait效果。 LongProcessAction.java 2. J

  • 本文向大家介绍详解Struts2拦截器机制,包括了详解Struts2拦截器机制的使用技巧和注意事项,需要的朋友参考一下 Struts2的核心在于它复杂的拦截器,几乎70%的工作都是由拦截器完成的。比如我们之前用于将上传的文件对应于action实例中的三个属性的fileUpload拦截器,还有用于将表单页面的http请求参数设置成action中对应的属性的param拦截器等。总之,在整个Struts

  • 主要内容:参考在Struts2中,可以设置或通过普通的<param>标签重写拦截器的参数。见下面的例子: 然而,在上面的代码片段,动作类被声明为自己的拦截器, 它会导致继承“defaultStack”拦截器的直接丢失。 如果你想保持“defaultStack”拦截器,并覆盖工作流的excludeMethods参数呢?没问题,试试这个: 上面的代码片段将保持“defaultStack”拦截并覆盖“workflow

  • 在这个问题中,我遇到了与Struts 2相反的问题:仅从defaultStack截取器中排除验证方法 上面的问题涉及到所有的方法都被排除在外,我的问题是没有任何方法被排除在外! 我正在尝试让authenticationInterceptor忽略LoginAction的showLogin方法: 但是,每次我转发到loginInitial时,拦截器都会抓取它,即使我的showLogin方法被排除在外。