1. 程式人生 > >經典三層框架初識(二)---Spring 2.2入門案例2補充

經典三層框架初識(二)---Spring 2.2入門案例2補充

咱們前面說的案例,要給UserServiceImpl中的成員屬性UserDao賦值,用的是在UserServiceImpl中建立setter方法.然後在配置檔案中配置如下的標籤

<bean id="userservice" class="service.impl.UserServiceImpl">
	<property name="dao" ref="userdao"></property>
</bean>

注意:<bean>中使用<property>子標籤是使用無參構造+setter方法建立我們需要的物件的

但是我們前面還說過,可以使用UserServiceImpl的構造方法來給員屬性UserDao賦值.那我們現在看一下:首先我們修改一下UserServiceImpl類的程式碼:

package service.impl;

import dao.UserDao;
import service.UserService;

public class UserServiceImpl implements UserService {
	
	private UserDao dao;
	//構造器
	public UserServiceImpl(UserDao dao) {
		super();
		this.dao = dao;
	}
	//set方法
      /*public void setDao(UserDao dao) {
		this.dao = dao;
	}*/

	@Override
	public void addUser() {
		dao.addUser();
	}

	@Override
	public void deleteUser() {
		dao.deleteUser();
	}

}

 如果我們不修改配置檔案,直接來在原來的測試類Test中執行,那會出現什麼情況呢?

這時候會出現下面的異常:沒有找到預設的構造器,也就是缺少無參構造

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userservice' defined in class path resource [applicationContext.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [service.impl.UserServiceImpl]: No default constructor found; nested exception is java.lang.NoSuchMethodException: service.impl.UserServiceImpl.<init>()

所以我們知道了,如果<bean>中使用<property>字標籤是預設呼叫無參的構造器和setter方法來建立的物件的.那我們這裡通過有參構造來實現該適合操作呢? ---我們使用<bean>中的<constructor-arg>這個字標籤來實現

<?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.xsd">

	<bean id="userdao" class="dao.impl.UserDaoImpl"></bean>
	<!-- 測試類中首先要得到一個UserService的實現類物件 我們做如下配置-->
 	<!-- 使用無參構造+setter方法建立物件 -->
	<!-- <bean id="userservice" class="service.impl.UserServiceImpl">
		<property name="dao" ref="userdao"></property>
	</bean> -->
	
	<!-- 使用有參構造 -->
	<bean id="userservice" class="service.impl.UserServiceImpl">
		<!-- 構造器引數: name:引數名稱 value:簡單型別 ref:引用 
			這裡面的name,value,ref和上面的使用setter方法的方式中<property>的屬性含義一樣 -->
		
		<constructor-arg name = "dao" ref = "userdao"></constructor-arg>
	</bean>
	
</beans>

此時我們在執行,結果就會正常顯示"新增使用者""刪除使用者"的正確結果了.除了上面這一種方式,其實還有第二種使用有參構造來建立物件的方法.我們從constructor-arg 這個標籤裡還發現一些別的東西里面除了name,ref屬性之外還有下面兩個屬性:
       index:引數的索引    第幾個引數  從0開始
       type:引數型別的型別 

我們來看一下用法:

<?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.xsd">

	<bean id="userdao" class="dao.impl.UserDaoImpl"></bean>
	<!-- 測試類中首先要得到一個UserService的實現類物件 我們做如下配置-->
 	<!-- 使用無參構造+setter方法建立物件 -->
	<!-- <bean id="userservice" class="service.impl.UserServiceImpl">
		<property name="dao" ref="userdao"></property>
	</bean> -->
	
	<!-- 使用有參構造 -->
        <bean id="userservice" class="service.impl.UserServiceImpl">
            <constructor-arg index = "0" ref = "userdao"></constructor-arg>
	</bean> -->
	
</beans>

我們構造引數只需要傳入一個物件引數,所以種類index的值自然就是0了,我們依舊可以用ref來給這個位於index=0的屬性賦值.

為什麼需要兩種方式呢?其實是因為有些程式碼不是我們自己寫的,咱們在沒有原始碼的情況下呼叫方法時,方法形式引數的顯示的是arg0,arg1..例如下面這樣

為了解決這種沒有解釋不容易辨認的情況.所以給了第二種,哪怕我們不知道引數名字,但是知道位置也可以建立物件.

注意:上面我們通過工廠模式建立的物件都是隻有一個成員屬性;不管是通過無參構造+setter方法  還是 有參構造 來建立物件,如果成員屬性不只一個,那我麼只要在配置檔案中為每一個屬性都配置一個<property>或<constructor-arg>標籤即可.2個成員屬性就寫兩個<property>或<constructor-arg>子標籤這樣.