《Spring揭秘》笔记——prototype作用域的“坑”
来源:互联网 发布:ubuntu登录界面循环 编辑:程序博客网 时间:2024/06/05 14:45
xml配置如下
<bean id="newsBean" class="com.tz.test.FXNewsBean" scope="prototype"></bean><bean id="mockPersister" class="com.tz.test.MockNewPersister"><property name="newsBean" ref="newsBean"></property> <!-- <lookup-method name="getNewsBean" bean="newsBean"/> --></bean>相关类如下
public class MockNewPersister implements IFXNewsPersister {private FXNewsBean newsBean;public void persisterNews(FXNewsBean newsBean){persisterNews();}public void persisterNews() {System.out.println(getNewsBean());}/** * 获取newsBean * @return newsBean newsBean */public FXNewsBean getNewsBean() {return newsBean;}/** * 设置newsBean * @param newsBean newsBean */public void setNewsBean(FXNewsBean newsBean) {this.newsBean = newsBean;}}
测试代码如下
ApplicationContext ctx = new ClassPathXmlApplicationContext("test.xml");MockNewPersister mock = (MockNewPersister) ctx.getBean("mockPersister");MockNewPersister mock2 = (MockNewPersister) ctx.getBean("mockPersister");mock.persisterNews();mock2.persisterNews();mock.persisterNews();打印结果如下
com.tz.test.FXNewsBean@59465d7dcom.tz.test.FXNewsBean@59465d7dcom.tz.test.FXNewsBean@59465d7dnewsBean被配置为prototype,那么容器每次给出的newsBean实例应该是不一样的,但是为什么最后打印的都是相同的呢?
原因不在于newsBean的scope是否是prototype的,而在于实例的取得方式。容器将一个FXNewsBean的实例注入到MockNewPersister之后,MockNewPersister会一直持有这个FXNewsBean实例的引用。虽然每次输出都调用了getNewsBean()方法返回了FXNewsBean的实例,但实际上每次返回的都是MockNewPersister持有的容器第一次注入的实例。换句话说,第一次实例注入后MockNewPersister再也没有重新向容器申请新的实例。所以,容器也不会重新为其注入新的FXNewsBean类型的实例。
解决问题的关键在于保证getNewsBean()方法每次从容器中取得新的FXNewsBean实例,而不是每次都返回其持有的单一实例。
解决方法之一是修改xml配置
<bean id="newsBean" class="com.tz.test.FXNewsBean" scope="prototype"></bean><bean id="mockPersister" class="com.tz.test.MockNewPersister"> <lookup-method name="getNewsBean" bean="newsBean"/></bean>这种方式称为方法注入,通过name属性指定需要注入的方法名,bean属性指定需要注入的对象,当getNewsBean()方法被调用时,容器可以每次返回一个新的FXNewsBean类型的实例。
以下是修改后的输出
com.tz.test.FXNewsBean@331545abcom.tz.test.FXNewsBean@3990f7c0com.tz.test.FXNewsBean@5c797bc6
解决方法之二是实现BeanFactoryAware接口
将MockNewPersister类修改如下
public class MockNewPersister implements IFXNewsPersister, BeanFactoryAware {private BeanFactory beanFactory;public void persisterNews(FXNewsBean newsBean) {persisterNews();}public void persisterNews() {System.out.println(getNewsBean());}public FXNewsBean getNewsBean() {return (FXNewsBean) beanFactory.getBean("newsBean");}@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {this.beanFactory = beanFactory;}}
xml配置文件修改如下
<bean id="newsBean" class="com.tz.test.FXNewsBean" scope="prototype"></bean><bean id="mockPersister" class="com.tz.test.MockNewPersister"><!-- <property name="newsBean" ref="newsBean"></property> --> <!-- <lookup-method name="getNewsBean" bean="newsBean"/> --></bean>输出如下
com.tz.test.FXNewsBean@2d0e39e6com.tz.test.FXNewsBean@fb4226com.tz.test.FXNewsBean@6fb3cd4a容器在实例化实现了该接口的bean定义的过程中,会自动将容器本身注入该bean。这样该bean就持有了它所处的BeanFactory的引用。实际上方法一的方法注入动态生成的子类,完成的是类似逻辑,只不过实现细节不同。
阅读全文
1 0
- 《Spring揭秘》笔记——prototype作用域的“坑”
- Spring-prototype作用域(图)
- Spring中Bean的作用域singleton, prototype
- Spring 的作用域 Singleton,Prototype, Session ,Request
- spring Bean的作用域(singleton&prototype)
- spring中bean的作用域single与prototype区别
- Spring 注解 @Scope("prototype") 的作用
- spring笔记——bean的作用域
- Spring实战学习笔记——bean的作用域
- 《Spring揭秘》笔记——Spring中两种容器比较
- Spring 中 bean 的作用域:singleton;prototype;WEB 环境作用域
- spring开发:spring的作用域(scope="prototype";scope="singleton")
- spring中bean的作用域属性single与prototype的区别
- spring中bean的作用域属性single与prototype的区别
- spring中bean的作用域属性single与prototype的区别
- Spring揭秘(十一)——Spring AOP的实现机制
- Spring容器中Bean的作用域之singleton和prototype
- 使用Spring(七)集合合并、bean的作用域(prototype,singleton)
- sohu高速源
- java 调用浏览器学习
- 匿名方法的一些使用方法备忘
- Git - 如何修改开源项目并推送给作者 / 克隆远程仓库到本地
- 关于JAVA中substring()和indexOf()的用法
- 《Spring揭秘》笔记——prototype作用域的“坑”
- 典型关联分析(Canonical Correlation Analysis)
- 排序之插入、归并、快速排序
- CSS样式覆盖规则
- 【异常】cvc-elt.1: 找不到元素 'beans'报错(ehcache-spring)
- instead of 触发器
- Android之Adapter解析
- 基于高德地图API实现车辆轨迹回放并显示实时坐标
- html2word html转换为word 使用docx4j