spring默认存在线程安全问题 !!!

1.struts1的action是单例的,所以存在线程安全问题,但是struts2的action不是单例所以是线程安全的

2.spring默认的注入也是单例的,所以存在线程安全问题

先理解为何会有线程不安全的问题,比如有一个类Person有个属性是name,线程1修改了这个属性的name,要进行存入数据库操作的时候,线程2又修改了这个name,这样线程1就存入了一个线程2修改过的数据了。(web环境是很容易出现多用户同时访问产生多线程的)

有一个类User,你每次使用这个类的时候都是new出来的,那么这个类一定是线程安全的吗?也不一定。

publicclassUser{privatestaticStringname=null;publicUser(Stringname){User.name=name;}}

对于这个User类,即使你每次都是new一个新的,它也不是线程安全的。

避免的方法很简单

spring管理bean,设置成scope为protype,如果是web运用设置成request这样就不是单例了,而是为每个线程都创建一个;

线程安全是可以避免的,就是禁止用可变动的成员变量,如果都是局部变量的话,即使是单例的也不存在任何问题

privateJdbcTemplatejdbcTemplate;

privateLobHandlerlobHandler;

里面没什么可变成员变量,说以他们是单例的,但是不会有线程问题

spring的生命周期范围:

singleton:SpringIoc容器只会创建该Bean的唯一实例,所有的请求和引用都只使用这个实例

Property:每次请求都创建一个实例

request:在一次Http请求中,容器会返回该Bean的同一个实例,而对于不同的用户请求,会返回不同的实例。需要注意的是,该作用域仅在基于Web的SpringApplicationContext情形下有效,以下的session和globalSession也是如此

session:同上,唯一的区别是请求的作用域变为了session

globalsession:全局的HttpSession中,容器会返回该bean的同一个实例,典型为在是使用portletcontext的时候有效(这个概念本人也不懂)

注意:如果要用到request,session,globalsession时需要配置

servlet2.4及以上:

在web.xml中添加:

<listener>

<listener-class>org.springframework.web.context.scope.RequestContextListener/>

</listener>

servlet2.4以下:

需要配置一个过滤器

<filter>

<filter-name>XXXX</filter-name>

<filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>

<filter-mapping>

<filter-name>XXXX</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

另外,从2.0开始,可以自己定义作用域,但需要实现scope,并重写get和remove方法

特别要引起注意的是:

一般情况下前面两种作用域是够用的,但如果有这样一种情况:singleton类型的bean引用一个prototype的bean时会出现问题,因为singleton只初始化一次,但prototype每请求一次都会有一个新的对象,但prototype类型的bean是singleton类型bean的一个属性,理所当然不可能有新prototpye的bean产生,与我们的要求不符

解决方法:

1.放弃Ioc,这与设计初衷不符,并代码间会有耦合

2,Lookup方法注入,推荐

相关推荐