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