有状态对象和无状态对象
参考:https://www.cnblogs.com/xubiao/p/6567349.html
一. 基本概念
有状态对象指的是有数据存储功能的类的对象。(就是类含有字段或属性,他的对象含有实例变量,可以保存数据)
有状态对象(Stateful Bean),就是有实例变量的对象,可以保存数据,是非线程安全的。
无状态对象就是一次操作的对象,不能保存数据的对象。
无状态对象(Stateless Bean),指的就是没有实例变量的对象,不能保存数据,是不可变类,是线程安全的对象。
二. 代码实现有状态对象和无状态对象
- Test类
package com.xiyou.activemq.po;import lombok.Data;/*** 这是一个实体类,该类是一个有状态对象,因为该类有实例变量*/@Data
public class Test {private Integer id;private String address;
}
- StatefulBeanService类
package com.xiyou.activemq.service;import com.xiyou.activemq.po.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;/*** 该类是一个有状态对象,因为里面有实例变量Test(并且Test并不是一个无状态对象)*/
@Service
public class StatefulBeanService {@Autowiredprivate Test test;public void test(){System.out.println("这是一个有状态对象,因为该类有实例变量Test(Test类是一个有状态的对象)");}}
- TestDao类
package com.xiyou.activemq.dao;import org.springframework.stereotype.Component;@Component
public class TestDao {public void test(){System.out.println("这里没有有状态对象,该类的对象就是一个无状态对象");}
}
- StatelessBeanService类
@Service
public class StatelessBeanService {// 虽然testDao是一个实例对象,但是该实例对象却是一个无状态对象,因此这个类也是一个无状态对象@Autowiredprivate TestDao testDao;public void testStatelessBean(){System.out.println("这是一个无状态对象,虽然这里有实例对象,但是该对象是一个无状态对象,因此这里也是一个无状态对象");}
}
三. Spring中的有状态和无状态
- 通过上面的分析,我们大概知道了什么是有状态对象,什么是无状态对象。无状态的Bean适用于不变模式,技术就是单例模式,这样单例模式j间的实例共享,能够提高性能。有状态的bean,多环境下不安全,适用于property原型模式。Property在每次对bean的请求都会创建一个bean的实例
- 默认情况下,Spring Bean的工厂取得的所有实例是singleton,容器只存在一个共享的bean
- scope的选择 (重要)
(1)有状态的bean都使用property作用域
(2)无状态的bean则使用singleton的作用域 - 如Service层和Dao层,直接用Singletob即可。虽然Service的类也有Dao这类的属性,但是Dao这些类都是没有状态信息的,也就是不变类,所以不影响。
四. Servlet是单例模式
Servlet体系结构是建立在Java多线程机制上的,他的生命周期是由Web容器负责的,一个Servlet类在Application中只有一个实例存在,也就是说有多个线程都在使用这个实例。这是单例模式的应用。无状态的单例模式是线程安全的,但是如果我们在Servlet中使用了实例变量,那么就变成了有状态的,就变成了singleton+有状态,这个就是非线程安全的。
总结一下:
- 无状态的单例模式是线程安全的
- 有状态的单例模式是线程不安全的
- 单例搭配无状态对象(singleton+无状态对象)
- 多例搭配有状态对象(property+有状态对象)