首先我们必须要先了解servlet的生命周期:
服务器只创建每个servlet的单一实例,首次创建servlet时,它的init方法会被调用,因此,init是放置一次性设置代码的地方,之后针对每个用户的请求都会创建一个线程,该线程调用前面创建的实例方法。多个并发请求一般会导致多个线程同时调用service(线程安全),service 方法会依据接受到HTTP请求的类型,调用doXXX方法。最后如果服务器卸载某个servlet就会调用servlet的destroy方法。
servlet是否线程安全?
通常情况下,系统只生成servlet的单一实例之后,为每个用户请求建立新的线程。如果很多请求同时到来,那么多个线程可能会并发的访问同一个 servlet对象。因此我们必须小心地同步对字段以及全局变量和其它共享数据的访问,因为多个线程可能同时对同一数据进行访问。(多个线程并不共享局部 变量)。
假设我们现在servlet定义了一个成员变量,在servlet初始化的时候,系统为该成员变量在堆中分配了内存空间,以后没每次访问服务器将不会再在堆里开辟内存空间,多人同时访问这个这个成员变量的时候,都会从同一块内存中获取。
下面我们来了解下struts1,2及spring的线程安全问题。
Struts1和Spring 都是单实例多线程,Struts2是多实例多线程的。Struts 2 Action对象为每一个请求产生一个实例,因此没有线程安全问题 。
《strut2权威指南》中有这么一段:
线程模式方面的对比:Struts1 Action是单例模式并且必须是线程安全的,因为仅有Action的一个实例来处理所有的请求。单例策略限制了Struts1 Action能做的事,并且要在开发时特别小心。Action资源必须是线程安全的或同步的;Struts 2 Action对象为每一个请求产生一个实例,因此没有线程安全问题 。
通过这文章知道,为什么struts1中并没有考虑到线程问题,因为所有的代码都是写在execute的方法中,所有变量都是定义在里面,所以没有线程安全问题。
而现在的struts2就不一样了。struts2的action中就像一个POJO一样,定义了很多的类变量。这就有线程安全问题了。。此时,就使用 scope=prototype来指定是个原型模式,而不是单例,这样就解决了线程安全问题。每个线程都是一个新的实例。。 所以相对来说,struts1 要多使用局部变量,而struts2使用 实例变量则不会产生不安全的结果。
spring的controller是单例的。
先看看spring的bean作用域有几种,分别有啥不同。
spring bean作用域有以下5个:
singleton:单例模式,当spring创建applicationContext容器的时候,spring会欲初始化所有的该作用域实例,加上lazy-init就可以避免预处理;
prototype:原型模式,每次通过getBean获取该bean就会新产生一个实例,创建后spring将不再对其管理;
====下面是在web项目下才用到的===
request:搞web的大家都应该明白request的域了吧,就是每次请求都新产生一个实例,和prototype不同就是创建后,接下来的管理,spring依然在监听
session:每次会话,同上
global session:全局的web域,类似于servlet中的application
好了,上面都说了spring的controller默认是单例,那很自然就是singleton了。
如果现在我们拿spring来管理struts2的话,那么默认的类就是单例的,如:
默认是单例,比如这样
<bean id="foo1" class="demo.scope.Foo" />
不指明scope就是单例的
如下这样配置的就是原型,每次生成bean的时候都新建一个实例
<bean id="foo2" class="demo.scope.Foo" scope="prototype"/>
Spring是通过ThreadLocal来实现线程安全的。如果一个对象要被多个线程访问。而该对象存在类变量被不同类方法读写,为获得线程安全,可以使用ThreadLocal来代替类变量。
我们知道在一般情况下,只有无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都 可以声明为singleton作用域。就是因为Spring对一些Bean(如RequestContextHolder、 TransactionSynchronizationManager、LocaleContextHolder等)中非线程安全状态采用ThreadLocal 进行处理,让它们也成为线程安全的状态,因为有状态的Bean就可以在多线程中共享了。 一般的Web应用划分为展现层、服务层和持久层三个层次,在不同的层中编写对应的逻辑,下层通过接口向上层开放功能调用。 在一般情况下,从接收请求到返回响应所经过的所有程序调用都同属于一个线程,如图9‑2所示: 这样你就可以根据需要,将一些非线程安全的变量以ThreadLocal存放,在同一次请求响应的调用线程中,所有关联的对象引用到的都是同一个变量。 由于①处的conn是成员变量,因为addTopic()方法是非线程安全的,必须在使用时创建一个新TopicDao实例(非singleton)。下面使用ThreadLocal对conn这个非线程安全的“状态”进行改造:
代码清单4 TopicDao:线程安全
import java.sql.Connection; import java.sql.Statement; public class TopicDao { ①使用ThreadLocal保存Connection变量 private static ThreadLocal connThreadLocal = new ThreadLocal(); public static Connection getConnection(){ ②如果connThreadLocal没有本线程对应的Connection创建一个新的Connection, 并将其保存到线程本地变量中。 if (connThreadLocal. get() == null) { Connection conn = ConnectionManager.getConnection(); connThreadLocal.set(conn); return conn; }else{ return connThreadLocal. get();③直接返回线程本地变量 } } public void addTopic() { ④从ThreadLocal中获取线程对应的Connection Statement stat = getConnection().createStatement(); } }
不同的线程在使用TopicDao时,先判断connThreadLocal.是否是null,如果是null,则说明当前线程还没有对应的Connection对象,这时创建一个Connection对象并添加到本地线程变量中;如果不为null,则说明当前的线程已经拥有了Connection对象,直接使用就可以了。这样,就保证了不同的线程使用线程相关的Connection,而不会使用其它线程的Connection。因此,这个TopicDao就可以做到singleton共享了。
相关推荐
通过Struts 2-Spring 插件,我们可以将Struts 2 的Action 对象交给Spring 来管理,Spring 负责初始化、配置和销毁这些对象。这样,Action 类不再需要自己去创建依赖的对象,而是通过构造函数或setter 方法接收Spring...
Struts2、Spring和Hibernate是Java Web开发中的三大框架,它们各自解决应用程序的不同问题,而将这三者整合在一起可以构建高效、灵活的企业级应用。Struts2作为MVC(Model-View-Controller)框架,负责处理用户请求...
整合Struts2和Spring2的主要目标是将Spring的DI功能引入到Struts2的Action类中,使得Action类的依赖可以在Spring容器中被管理。这样,Action类不再需要自行创建依赖对象,而是通过Spring来获取,增强了代码的可维护...
在Struts2和Spring整合中,可以使用Spring提供的拦截器,例如`org.springframework.web.struts.DelegatingInterceptor`,它能让Spring容器处理Action的实例化。 7. **事务管理**:Spring提供了强大的事务管理功能。...
Struts2-Spring-Plugin-2.2.1.jar 是一个专门为 Struts2 框架与 Spring 框架集成而设计的插件。...为了更好地利用这个插件,开发者需要对Struts2和Spring框架有深入的理解,同时也需熟悉它们的配置和API使用。
Struts2和Spring3是两个非常流行的Java Web框架,它们分别负责MVC模式中的Action层和依赖注入(DI)及面向切面编程(AOP)。将这两个框架整合在一起可以实现更高效、更灵活的Web应用开发。然而,在整合过程中,可能...
Struts2和Spring是两种非常重要的Java Web开发框架,它们在企业级应用中广泛使用。Struts2提供了MVC(模型-视图-控制器)架构,帮助开发者更好地组织和管理应用程序逻辑,而Spring则是一个全面的后端框架,提供依赖...
对于Struts2和Spring的配置,我们需要在`struts.xml`和`spring-context.xml`文件中进行相应的设置,例如定义Action类、配置Spring Bean以及指定Struts2与Spring的整合方式。同时,确保web.xml文件中配置了...
Struts2、Spring和MyBatis是Java Web开发中经典的三大框架,它们分别负责MVC模式中的控制层、业务层和服务层。EasyUI则是一个基于jQuery的UI组件库,用于快速构建美观且响应式的Web应用界面。下面我们将深入探讨这三...
Struts2和Spring是两个非常重要的Java开源框架,它们在企业级Web开发中扮演着核心角色。Struts2是一个强大的MVC(Model-View-Controller)框架,它为构建基于J2EE的Web应用程序提供了全面的解决方案。而Spring则是一...
4. **整合Spring和Struts2**:使用Spring的Struts2插件,使Spring管理的Bean可以直接在Struts2 Action中注入使用。 5. **整合Spring和MyBatis**:通过Spring的SqlSessionFactoryBean,将MyBatis的SqlSessionTemplate...
Spring4则作为整个应用的容器,管理所有Bean,包括Struts2的Action,以及业务服务和DAO(数据访问对象)。Hibernate则在Spring4的管理下,处理数据持久化操作,将业务对象与数据库进行交互。 至于Apache Tomcat,它...
在Java Web开发中,Struts2和Spring是两个非常重要的框架。Struts2是一个MVC(Model-View-Controller)框架,主要用于控制应用程序的流程,而Spring则是一个全面的后端解决方案,包括依赖注入、AOP(面向切面编程)...
Struts2、Spring和Hibernate是Java Web开发中的三大框架,它们各自在应用程序的不同层面发挥着重要作用。Struts2作为MVC(模型-视图-控制器)框架,负责处理请求和展示视图;Spring是一个全面的后端解决方案,提供...
3. **Struts2的插件机制**:Struts2提供了Spring插件,该插件负责连接Struts2和Spring,允许Struts2通过Spring获取Action实例。这需要在struts.xml配置文件中添加相应的配置。 4. **AOP代理**:Spring的AOP功能可以...
Struts2+Spring+Hibernate 中的Action单元测试环境搭建 在软件开发中,单元测试是一种非常重要的测试方法,可以帮助我们确保代码的可靠性和稳定性。在 Struts2+Spring+Hibernate 框架中,对 Action 的单元测试环境...
Struts2+Spring+Hibernate和Struts2+Spring+Ibatis是两种常见的Java Web应用程序集成框架,它们分别基于ORM框架Hibernate和轻量级数据访问框架Ibatis。这两种框架结合Spring,旨在提供一个强大的、可扩展的、易于...
Struts2和Spring是两种非常重要的Java Web开发框架,它们在企业级应用中广泛使用。Struts2主要用于处理MVC(Model-View-Controller)架构中的控制器部分,而Spring则是一个全面的轻量级框架,提供了包括依赖注入、...
通过这样的配置,Struts2和Spring可以协同工作,提供一个强大且灵活的Java Web开发环境。 总之,Struts2-Spring-Plugin是两个优秀框架的结合,旨在提升开发效率,降低耦合度,提高应用的可维护性和可扩展性。在实际...