提问: web中singleton的范围,spring中singleton的范围
自从学java开始就会知道singleton是虚拟机范围的,也就是说一个singleton的对象被创建后虚拟机内是唯一的.
但是 web应用中用户很多.大家都在访问应有服务器.如果一个类被写成singleton的,服务器的jvm中也就只有一个对象了(所以应用服务器下也就只有一个了).大家同时操作这个对象.所以要求这个对象中不要有别的数据对象.
---- 以上是我对singleton的理解.
但是在用spring的时候.我疑惑了.
我用spring和ibatis集成.配置文件很简单如下:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"><beans> <!--1. 配置数据源 --> <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" singleton="false"> <property name="driverClassName" value="net.sourceforge.jtds.jdbc.Driver"/> <property name="url" value="jdbc:jtds:sqlserver://localhost:1433/EE"/> <property name="username" value="sa"/> <property name="password" value="1234"/> </bean> <!--2. 配置sqlMapClient 相当于hibernate的sessionFactory --> <bean id="mySqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"> <property name="configLocation" value="ibatisConfig/ibatisConfig.xml"/> <property name="dataSource" ref="myDataSource"/> </bean> <!--3. 配置DAO --> <bean id="userDaoAtXml" class="cn.luyu.ssi.dao.Impl.UserDaoImpl"> <property name="dataSource" ref="myDataSource"/> <property name="sqlMapClient" ref="mySqlMapClient"/> </bean> <!--4. 配置服务类 --> <bean id="userServiceTarget" class="cn.luyu.ssi.service.Impl.UserServiceImpl"> <property name="userDao" ref="userDaoAtXml"/> </bean> <!--5. 配置事务管理器TransactionManager --> <bean id="myTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="myDataSource"/> </bean> <!--6. 配置事务代理 --> <bean id="abstrac" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true"> <property name="transactionManager" ref="myTransactionManager"/> <property name="transactionAttributes"> <props> <!--把CustomBuyException减去.说明它即使不是runtimeException,也会rollback--> <!--把CustomBuyException加上.说明它即使是runtimeException,也不会rollback--> <prop key="*">-DataAccessException</prop> </props> </property> </bean> <!-- 继承abstrac 方便多个service来映射 --> <bean id="userService" parent="abstrac"> <property name="target" ref="userServiceTarget"/> </bean></beans>
但是userServiceTarget和TransactionManager 要写成什么范围的呢?
网上查了资料说spring中singleton的是指在beanfactory范围呢的.这句话也让我疑惑.
请大侠给点指点.或推荐点书籍!!感谢
[解决办法]
此单实例非彼单实例。
Spring的singleton是容器级的,我们一般说的singleton模式是JVM级的。所以singleton模式中,singleton的class在整个JVM中只有一个instance,Spring的Bean,你可以一个class配置多个Bean,这个class就有了多个instance。这个singleton是指在spring容器中,这个Bean是单实例的,是线程共享的。所以要求这些类都是线程安全的。也就是说,不能出现修改Bean属性的方法,当然除了设值得那些setter。只要满足线程安全,这些bean都可以用singleton。而且我们在绝大多数使用上,也是这样用的,包括dao,service。
[解决办法]
singleton 单例的,整个过程都是一个实例,如果你的service,dao里面仅仅是一些方法,没有表示状态的东西的话,就没有问题,而且还会提高性能。
[解决办法]
Beanfactory是Spring初始以静态方式载入的,Spring的单例IOC是基于容器级的,所以这你都不用担心与考虑.
[解决办法]
给你写个例子:
public class XxxBean { private int size; public void setSize(int size) { this.size = size; //虽然改变了属性值,但是这是个setter } public void someOper1(){ int t = size*100; //读取属性值,没问题 } public void someOper2(){ this.size = 100; //错误!修改了属性的值!! }}
[解决办法]
开发的时候尽量少定义类的变量,把变量放在方法里,只定义dao,log等变量在类里边就可以了
[解决办法]
要用spring就要遵守spring的规则。而且,spring管理的Bean都是一些服务性的对象,本身也不应该有状态的修改。
没你想象的可怕,spring出来这么多年了,用的项目那么多,哪个项目不都是团队开发的,挺正常的。