spring在一个单例(singleton)的对象中,不能通过常规的方法来注入多例(prototype)对象


代码
package cn.com.leadfar.spring;
 
public class UserAction extends BaseAction{
 
public String add(){
//System.out.println("add");
service.addUser();
return "success";
}
 
public void upload(){
service.uploadExcel(null);
}
}
package cn.com.leadfar.spring;
userService
import java.io.File;
 
public class UserService {
 
private ExcelTransfer transfer;
public String addUser(){
System.out.println("userservice.addUser");
return "success";
}
 
public void uploadExcel(File f){
transfer.transfer(f);
}
public void setTransfer(ExcelTransfer etf){
this.transfer = etf;
}
}
package cn.com.leadfar.spring;
 
import java.io.File;
/**
* 本类型是有状态的,每次获得这个对象的时候,都必须是不同的对象(prototype)
* @author lenovo
*
*/
public class ExcelTransfer {
//状态
private int currentRow;
public String transfer(File excelFile){
System.out.println("现在正在用【"+this+"】对象,转换Excel文件");
return "转换后的结果";
}
}
beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="baseAction" class="cn.com.leadfar.spring.BaseAction" scope="prototype" >
<property name="MyUserService" ref="userService"></property>
</bean>
<bean id="userAction" class="cn.com.leadfar.spring.UserAction" scope="prototype" parent="baseAction">
 
</bean>
<bean id="userService" class="cn.com.leadfar.spring.UserService" scope="singleton">
<property name="Transfer" ref="excelTransfer"></property>
</bean>
<bean id="excelTransfer" class="cn.com.leadfar.spring.ExcelTransfer" scope="prototype"></bean>
</beans>
public void test04(){
 
BeanFactory factory = new ClassPathXmlApplicationContext("beans.xml");
UserAction action1 = (UserAction) factory.getBean("userAction");
action1.upload();
 
UserAction action2 = (UserAction) factory.getBean("userAction");
action2.upload();
 
UserAction action3 = (UserAction) factory.getBean("userAction");
action3.upload();
}
输出
现在正在用【cn.com.leadfar.spring.ExcelTransfer@1f64158】对象,转换Excel文件
现在正在用【cn.com.leadfar.spring.ExcelTransfer@1f64158】对象,转换Excel文件
现在正在用【cn.com.leadfar.spring.ExcelTransfer@1f64158】对象,转换Excel文件
为什么ExcelTransfer配置的是prototype输出确实单例 是因为
<bean id="userService" class="cn.com.leadfar.spring.UserService" scope="singleton">
是单利模式 这种情况下多李晔变成单例
在UserService是把ExcelTransfer作为它的实例变量一开始创建对象的时候spring给他注入进去的那个对象 然后因为UserService一直没有重新创建 所以UserService里面的transfer实例变量一直不能被销毁也就是刚开始给他注入进去的那个对象所以这就有问题了
总结:
在一个单例的对象 如果我想得到多利的对象应该怎么样得到
public void uploadExcel(File f){
//此种方式相当于绕过了spring
//如果ExcelTransfer还依赖于别的对象呢也是有spring注入的 你直接NEW就相当于绕过了spring
//那些对象铁定是注入不了的这种情况下也不能正常运行
//所以不能用这种方式创建ExcelTransfer
ExcelTransfer transfer = new ExcelTransfer();
transfer.transfer(f);
}
解决方法
单例对象调用多例对象不能使用常规的注入方法,
private ExcelTransfer transfer;
public void setTransfer(ExcelTransfer etf){
this.transfer = etf;
}
public class UserService implements BeanFactoryAware {
//private ExcelTransfer transfer;
private BeanFactory factory;
public String addUser(){
System.out.println("userservice.addUser");
return "success";
}
//把spring当成是工厂由工厂生产对象
public void uploadExcel(File f){
ExcelTransfer transfer = (ExcelTransfer) factory.getBean("excelTransfer");
transfer.transfer(f);
}
/*public void setTransfer(ExcelTransfer etf){
this.transfer = etf;
}*/
 
@Override
public void setBeanFactory(BeanFactory f) throws BeansException {
this.factory = f;
}
}
测试
现在正在用【cn.com.leadfar.spring.ExcelTransfer@1cd107f】对象,转换Excel文件
现在正在用【cn.com.leadfar.spring.ExcelTransfer@1f64158】对象,转换Excel文件
现在正在用【cn.com.leadfar.spring.ExcelTransfer@3c2378】对象,转换Excel文件
这是在spring应用中的一个典型案例


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM