关于spring的scope="prototype"问题

Mr__anto 2014-01-12 03:06:20
<bean id="product" class="sys.pojo.Product" scope="prototype"/>

<bean id="cart" class="sys.pojo.Cart" scope="prototype">
<property name="product" ref="product"/>
</bean>

<bean id="productService" class="sys.service.ProductService">
<property name="productDao" ref="productDao"/>
<property name="cart" ref="cart"/>
</bean>

在Cart类中添加了product的setter和getter
在ProductService类中也添加了cart的setter和getter
在ProductService类的一个方法里使用cart,并设置属性,但是当再次调用这个方法的时候,原先设置的属性就被覆盖了,但是设置了scope="prototype",怎么还说单例?
...全文
2205 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
christmaz 2016-07-28
  • 打赏
  • 举报
回复
引用 11 楼 h8170358 的回复:
精华帖。。。。第一次体会到单例多例的使用,好像突然明白了一点设计模式。
多看看各种框架,就是各种设计模式的实现。为什么一般觉得设计模式不常用?因为框架都给你弄好了不用你弄。
  • 打赏
  • 举报
回复
精华帖。。。。第一次体会到单例多例的使用,好像突然明白了一点设计模式。
tzp19910827 2014-01-13
  • 打赏
  • 举报
回复
引用 7 楼 u013173912 的回复:
[quote=引用 4 楼 tzp19910827 的回复:] 这个可能是线程安全性的问题,在service方法中,不要把entity设为属性,因为一般service都是单例,当多个并发调用的时候,就是存在覆盖属性值的问题。这是线程安全性的问题。 因为你的service是单例的,每次调用的时候,你的cart就被覆盖了,虽然cart是prototype的,但是setter方法是在创建实例的时候,容器调用一次,所以你的service每次被调用,cart不会每次被创建一个新的实例。 不知道说清楚没有。 建议是entity不要设置为属性,每次用的时候最好是new一个。setter方法在容器初始化的时候只被调用一次。除非你在代码中context.getBean(),这样才会原型的每次都创建一个新的对象。
你的意思是说尽管cart是prototype的,但service是单例的,只会被实例化一次,所以作为他的属性cart也还是单例。那如果把service也设置为prototype,应该就就可以了吧,方便的同时估计也带来其他的影响。[/quote] 我连续发了三个回复,我觉得我应该讲清楚了,确实是service是单例的,那么在容器初始化的时候setter只被调用了一次,那么也就是说cart也就只被获得了一次,当然你cart设成原型也就没有了什么意义。 解决方式两种: 1、service也设成原型,那么每个service都是独立的,自然不会有什么影响。 2、cart不要设为属性,在方法中new 或者context.getBean(),这样也能保证pojo是独立的。
mjygz 2014-01-12
  • 打赏
  • 举报
回复
对了,实体类用prototype,貌似这种用法很少啊,都是action用prototype
mjygz 2014-01-12
  • 打赏
  • 举报
回复
觉得问题找到了,新的问题是怎么解决这个新的问题 service单例,看楼下的
Mr__anto 2014-01-12
  • 打赏
  • 举报
回复
引用 4 楼 tzp19910827 的回复:
这个可能是线程安全性的问题,在service方法中,不要把entity设为属性,因为一般service都是单例,当多个并发调用的时候,就是存在覆盖属性值的问题。这是线程安全性的问题。 因为你的service是单例的,每次调用的时候,你的cart就被覆盖了,虽然cart是prototype的,但是setter方法是在创建实例的时候,容器调用一次,所以你的service每次被调用,cart不会每次被创建一个新的实例。 不知道说清楚没有。 建议是entity不要设置为属性,每次用的时候最好是new一个。setter方法在容器初始化的时候只被调用一次。除非你在代码中context.getBean(),这样才会原型的每次都创建一个新的对象。
你的意思是说尽管cart是prototype的,但service是单例的,只会被实例化一次,所以作为他的属性cart也还是单例。那如果把service也设置为prototype,应该就就可以了吧,方便的同时估计也带来其他的影响。
tzp19910827 2014-01-12
  • 打赏
  • 举报
回复
或者你的service也设置成prototype的,每次调用的时候,容器会创建一个新的service,这样它的属性才不会冲突,struts2的action就是这样做的,因为它的属性封装了表单数据,所以每次调用是创建了一个新的action,这个是线程安全的东西。如果不是很理解,可以参考一下struts2的action的线程安全,网上搜一下理解一下就好了。
tzp19910827 2014-01-12
  • 打赏
  • 举报
回复
如果你非要用spring管理entity,那么就在需要的时候用context.getBean(),每次重新获得一个,这样容器才会每次给你创建一个新的对象。setter方法在容器初始化的时候只调用一次,你的service的属性cart其实一直都是一个。
tzp19910827 2014-01-12
  • 打赏
  • 举报
回复
这个可能是线程安全性的问题,在service方法中,不要把entity设为属性,因为一般service都是单例,当多个并发调用的时候,就是存在覆盖属性值的问题。这是线程安全性的问题。 因为你的service是单例的,每次调用的时候,你的cart就被覆盖了,虽然cart是prototype的,但是setter方法是在创建实例的时候,容器调用一次,所以你的service每次被调用,cart不会每次被创建一个新的实例。 不知道说清楚没有。 建议是entity不要设置为属性,每次用的时候最好是new一个。setter方法在容器初始化的时候只被调用一次。除非你在代码中context.getBean(),这样才会原型的每次都创建一个新的对象。
Mr__anto 2014-01-12
  • 打赏
  • 举报
回复
如果用spring管理,那该怎么修改
still-me 2014-01-12
  • 打赏
  • 举报
回复
一般,JavaBean都不用交给spring管理吧,要用的时候直接new就行了,因为它封装了业务数据。

67,514

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧