大家都知道,struts1.2由于是线程安全的,每一个请求都去实例化一个action,造成大量并发时的资源浪费。
struts2在这一点上做了改进,每个action都是一个singleton,所有的请求都是请求同一个action实例。这样在一定程度上能节约资源,但又有安全问题。最常见的就是在action中声明有块状的实例变量,因为这一点是不被提倡的。如果一定要声明,那一定要加上同步块。
那么在spring mvc中的controller是不是线程安全的呢?答案是否定的。controller在默认情况下也是非线程安全的,我们来看看源码:
* @author John A. Lewis
* @author Juergen Hoeller
* @since 2.0
* @see ResourceAwareController
* @see EventAwareController
*/
public abstract class AbstractController extends PortletContentGenerator implements Controller {
[color=red]private boolean synchronizeOnSession = false;[/color]
由上面源码可知,controller默认是非安全的。
public void handleActionRequest(ActionRequest request, ActionResponse response) throws Exception {
// Delegate to PortletContentGenerator for checking and preparing.
check(request, response);
// Execute in synchronized block if required.
//只有synchronizeOnSession设置为true,才会同步处理请求
if (this.synchronizeOnSession) {
PortletSession session = request.getPortletSession(false);
if (session != null) {
synchronized (session) {
handleActionRequestInternal(request, response);
return;
}
}
}
handleActionRequestInternal(request, response);
}
只有手工设置controller的synchronizeOnSession值为true,才会被同步处理。
因此,我们在使用spring mvc 的contrller时,应避免在controller中定义实例变量。
##### 更正 ####################################
由于在下对struts1.x的理解也来自网络,给大家带来不便,还请见谅。
经过对struts1.x源码的研读发现:
struts1.2获取action的方式是单例的,所有的action都被维护在一个hashMap里,当有请求到达时,先根据action的名称去hashMap里查找要请求的Action是否已经存在,如果存在,则直接返回hashMap里的action。如果不存在,则创建一个新的Action实例。
下面我们来分析一下源码:
请求到达ActionServlet时,首先会到达doGet()或doPost()方法,而ActionServlet转给了process()方法进行统一处理
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
process(request, response);
}
而process()方法又会转给processor的process()方法进行处理
protected void process(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
...
processor.process(request, response);
}
processor的process()方法里经过一系列处理后,最后通过processActionCreate方法来返回一个具体的action实例
public void process(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
...
// Create or acquire the Action instance to process this request
Action action = processActionCreate(request, response, mapping);
if (action == null) {
return;
}
...
}
那我们就到processActionCreate这个方法里去一窥究竟吧:
1、先获取类名
2、根据类名去map里查寻实例是否已经存在
3、如果存在,则直接返回
4、如果不存在,则创建一个新实例
5、把创建好的action放到map里备用
protected Action processActionCreate(HttpServletRequest request,
HttpServletResponse response,
ActionMapping mapping)
throws IOException {
// Acquire the Action instance we will be using (if there is one)
String className = mapping.getType();//1、先获取类名
...
Action instance = null;
synchronized (actions) {
// Return any existing Action instance of this class
instance = (Action) actions.get(className);//2、根据类名去map里查寻实例是否已经存在
if (instance != null) {
return (instance); //3、如果存在,则直接返回
}
// Create and return a new Action instance
//4、如果不存在,则创建一个新实例
instance = (Action) RequestUtils.applicationInstance(className)
instance.setServlet(this.servlet);
actions.put(className, instance);//5、把创建好的action放到map里
}
...
return (instance);
}
我们再来看看actions的定义:
/**
* The set of Action instances that have been created and
* initialized, keyed by the fully qualified Java class name of the
* Action class.
*/
protected HashMap actions = new HashMap();
结论:
struts1.2获取action的方式是单例的,所有的action都被维护在一个hashMap里,当有请求到达时,先根据action的名称去hashMap里查找要请求的Action是否已经存在,如果存在,则直接返回hashMap里的action。如果不存在,则创建一个新的Action实例。
分享到:
相关推荐
1. **设计模式实践**:Spring源码中大量运用了工厂模式、单例模式、观察者模式等设计模式,学习源码能加深对设计模式的理解。 2. **性能优化**:通过对源码的学习,开发者可以了解Spring如何进行性能优化,如缓存、...
3. **深入Spring MVC**:分析`DispatcherServlet`的请求处理流程,以及`HandlerMapping`和`HandlerAdapter`的角色。 4. **探究数据访问模块**:查看Spring如何与JDBC、ORM框架集成,以及事务管理的实现。 5. **注解...
标题中的“spring源码关键地方”指的是一项关于Spring框架核心源码的深入解析。Spring是Java企业级应用开发中最常用的框架之一,它的源码分析对于开发者来说具有极高的学习价值,可以帮助理解其工作原理,提升开发...
5. **源码分析**:通过研究Spring3.x的源码,开发者可以学习到如何设计和实现一个强大的、灵活的框架。源码中的注释和设计模式的使用,可以帮助理解Spring如何处理各种常见的编程挑战,如并发、线程安全和资源管理。...
【Java图书管理系统源码解析】 本项目是一个基于Java语言开发的图书馆管理系统,是某大学生的毕业设计作品。作为学习和研究的资源,它提供了一整套的源代码、系统说明和程序结构文档,对于深入理解Java编程以及软件...
**Spring WebFlux 概述** Spring WebFlux 是 Spring Framework 的一部分,它引入了一种反应式编程模型,用于构建高度可伸缩、非阻塞的 Web ...通过阅读和分析项目源码,你将掌握Spring WebFlux的核心概念和实践技巧。
2. 创建SqlSessionTemplate:SqlSessionTemplate是Spring封装的SqlSession,提供了线程安全的操作,避免了手动管理和关闭SqlSession。 3. 映射Mapper接口:MyBatis的Mapper接口可以直接在Spring中作为bean使用,...
10. **源码分析**:深入阅读Spring源码,可以帮助我们理解其内部设计思想,如事件驱动、设计模式的应用(如单例、工厂、装饰者等)、类加载机制以及线程安全等Java编程基础。 以上只是Spring框架中部分关键知识点的...
10. **源码分析**:通过分析EasyJF官网的源码,开发者可以学习到实际项目中的最佳实践,以及如何将EasyJF框架应用到实际项目中。 11. **版本控制**:源码可能使用Git或其他版本控制系统管理,学习如何使用这些工具...
在"java-study-master"这个压缩包中,可能包含了上述知识点的实践示例和详细讲解,包括代码结构、配置文件、源码分析等,可以帮助学习者深入理解Java和SpringBoot的使用。通过系统地学习和实践,开发者可以提升自己...
JForum的源码分析可以帮助开发者了解如何使用Java进行Web开发,特别是对于MVC(Model-View-Controller)设计模式的应用。该项目可能采用了Servlet和JSP技术来处理HTTP请求和展示视图,使用了JDBC来与数据库交互,还...
8. **多线程和并发**:考虑到论坛的高并发访问,源码中可能会使用到多线程和并发控制技术,如synchronized关键字、Lock接口等,来保证数据的一致性和服务的高可用性。 9. **缓存技术**:为了提高性能,论坛系统可能...
【标题】:基于Java的酒店管理系统源码分析 在IT行业中,Java是一种广泛使用的编程语言,尤其在企业级应用开发中占据着主导地位。本篇文章将深入探讨一个基于Java的酒店管理系统源码,旨在帮助开发者了解如何利用...
Spring框架是Java开发中不可...通过深入研究Spring的源代码,你可以学习到设计模式的应用,如工厂模式、单例模式、代理模式等,以及如何优雅地处理并发、线程安全等问题。这将极大地提高你的编程水平和解决问题的能力。
通过分析和研究这个项目源码,我们可以深入掌握Java编程基础、网络通信技术以及可能涉及的短信服务API使用。 1. **Java编程基础**: 项目中的源码展示了Java面向对象编程的基本原则,包括类的设计、对象的创建与...
Kaya-CMS可能使用Spring Security或Apache Shiro等组件实现用户认证和授权,确保内容的安全访问。 6. **模块化设计**:为了方便功能扩展,Kaya-CMS可能会采用模块化设计,将功能拆分为独立的组件,便于单独开发和...
**Java源码医疗-Medigy Java:开源医疗应用框架套件** Medigy Java是一个专为医疗行业设计的开源应用框架套件,它基于Java技术,提供了丰富的功能和工具,以帮助开发者快速构建高效、安全、合规的医疗信息系统。在...
新增全新的springboot2的框架技术点(代码位于当前仓库的spring-boot2-study目录下) 基于springboot 2.0.6.RELEASE版本实现的代码演示集合,欢迎使用star / fork 新子项目列表 介绍Springboot2【自动化单元测试】的...
Spring Security或Apache Shiro等安全框架可以用于实现这一目标。 7. 文档部分:通常会包含系统设计文档、需求分析、数据库设计、使用手册等,帮助开发者理解整个系统的架构和功能。 在实际开发过程中,可能会采用...
这个源码分析将帮助我们深入理解Struts 1.2的工作原理和内部机制。 1. **MVC架构** - Model:在Struts 1.2中,模型通常由JavaBean或业务服务对象(Business Service Objects, BSOs)组成,负责处理业务逻辑。 - ...