springmvc的controller默认是singleton的(非线程安全的)。在使用springmvc的controller时,应避免在controller中定义实例变量。
要想使用实例变量解决的方法是
(1)在controller中使用threadlocal变量;
(2)在spring配置controller中声明scope=prototype,每次都创建新的controller。
理解有状态和无状态基本概念:
有状态对象(Stateful Bean),就是有实例变量的对象 ,可以保存数据,是非线程安全的。一般是prototype scope。
无状态对象(Stateless Bean),就是没有实例变量的对象,不能保存数据,是不变类,是线程安全的。一般是singleton scope。
而Service内部一般只有dao实例变量 如userDao, 因为userDao是无状态的对象(内部无实例变量且不能保存数据),所以service也是无状态的对象。
springMVC中,一般Controller、service、DAO层的scope均是singleton。
每个请求都是单独的线程,即使同时访问同一个Controller对象,因为并没有修改Controller对象,相当于针对Controller对象而言,只是读操作,没有写操作,不需要做同步处理。
Service层、Dao层用默认singleton就行,虽然Service类也有dao这样的属性,但dao这些类都是没有状态信息的,也就是 相当于不变(immutable)类,所以不影响。