1. 程式人生 > >例項化Bean的方法(基於xml配置)

例項化Bean的方法(基於xml配置)

Spring IoC容器 根據基於xml的配置元資料(configuration metadata),使用反射機制來建立Bean的例項。

建立的方法有三種:

1. 通過構造器<constructor-arg/>

1.1 使用空構造器進行定義。類中必須有空構造器(可以是預設的)

空構造器中沒有傳入引數,bean的配置只需要一個定義名就可以了。

<bean id="beanID" class="com.szse.beans.HelloApiImpl "> </bean>

例子:

介面HelloApi.java

package com.szse.beans;

public interface HelloApi {
	
	public void sayHello();

}

它的實現類HelloApiImpl.java

package com.szse.beans;

public class HelloApiImpl implements HelloApi{

	private int num;
	private String message;
	
	public HelloApiImpl(){
		num = 1;
		message = "Hello world!"; 
	}
	
	@Override
	public void sayHello() {

		System.out.println(num + ":" + message);

	}
}

配置檔案HelloWorld.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
      xmlns="http://www.springframework.org/schema/beans"  
      xsi:schemaLocation="http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans-4.2.xsd">   

<bean id="firstBean" class="com.szse.beans.HelloApiImpl "> 
</bean>
</beans>
單元測試類TestHello.java
package com.szse.beans;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestHello {
	@Test
	public void testInstantiatingBeanByConstructor() {
		//使用構造器
		ApplicationContext ctx = 
	new ClassPathXmlApplicationContext("HelloWorld.xml");
		HelloApi firstBean = ctx.getBean("firstBean", HelloApi.class);
		firstBean.sayHello();
	}
}
輸出 1:Hello world! 1.2 帶參構造器,類中有帶參的構造方法 ①根據引數索引(index) <bean id="beanID" class="com.szse.beans.HelloApiImpl ">        <constructor-arg  index=" " value=" "/> </bean> index表示構造器的第幾個引數,從0開始,value即為該引數的值。 例子: 在HelloApiImpl.java新增
public HelloApiImpl(int num,String message){
		this.num = num;
		this.message = message; 
	}

在HelloWorld.xml檔案中新增
<bean id="secondBean" class="com.szse.beans.HelloApiImpl ">  
	<constructor-arg index="0" value="2" />
	<constructor-arg index="1" value="Hello spring!" />
</bean>
在TestHello.java的測試方法,保留第一個例子作為對比
@Test
	public void testInstantiatingBeanByConstructor() {
		//使用構造器
		ApplicationContext ctx = 
	new ClassPathXmlApplicationContext("HelloWorld.xml");
		HelloApi firstBean = ctx.getBean("firstBean", HelloApi.class);
		firstBean.sayHello();
		HelloApi secondBean = ctx.getBean("secondBean", HelloApi.class);
		secondBean.sayHello();
	}


輸出1:Hello world!
       2:Hello spring!

②根據引數型別(type)

將上面的secondBean配置改為如下

<bean id="secondBean" class="com.szse.beans.HelloApiImpl ">  
	<constructor-arg type="int" value="2" />
	<constructor-arg type="java.lang.String" value="Hello spring!" />
</bean>

若是java基礎型別,type可以直接指定該型別,其他都要用全類名。

測試方法不變,大家可以自己執行一遍試試結果是否一樣。

③根據引數名(name)

將上面的secondBean配置改為如下

<bean id="secondBean" class="com.szse.beans.HelloApiImpl ">  
	<constructor-arg name="num" value="2" />
	<constructor-arg name="message" value="Hello spring!" />
</bean>

測試方法不變,大家可以自己再執行一遍試試結果是否一樣。

注:這裡解釋順便給大家加深一下 對 “bean的例項是由IoC容器主動建立,而不是由我們自己建立”  這句話的理解。可以在構造器中加上System.out.println(”print sth…")。

測試方法中只保留這一句:

ApplicationContext ctx =
    new ClassPathXmlApplicationContext("HelloWorld.xml");

執行輸出,看看是不是我們xml檔案中配置了幾個bean就會打印出幾個“print sth…”。

所以,ApplicationContext載入XML檔案時就會建立好所有bean的例項,我們用的時候只需要getBean()就可以了。

2. 使用靜態工廠方法

<bean id="beanID" class="com.szse.beans.HelloApiStaticFactory"factory-method="newInstance">

 </bean>

注意這裡的class屬性是靜態工廠類,而不是該bean的類。使用factory-method屬性來確定哪個靜態工廠方法建立的bean例項。

Spring呼叫工廠方法(也可以包含一組引數),並返回一個有效的物件。如果靜態工廠方法需要引數,使用<constructor-arg>元素傳入。

例子

靜態工場類HelloApiStaticFactory.java

package com.szse.beans;

public class HelloApiStaticFactory {
	//工廠方法
	public static HelloApi newInstance(int num,String message) {
	//返回需要的Bean例項
	return new HelloApiImpl(num,message);
	}
}

xml中加上

<bean id="thirdBean" class="com.szse.beans.HelloApiStaticFactory" factory-method="newInstance">  
	<constructor-arg name="num" value="3" />
	<constructor-arg name="message" value="Hello Jane!" />
</bean>


測試類中加上方法

@Test
	public void testInstantiatingBeanByFactory() {
			//使用工場方法
		ApplicationContext ctx = 
		new ClassPathXmlApplicationContext("HelloWorld.xml");
		HelloApi thirdBean = ctx.getBean("thirdBean", HelloApi.class);
		thirdBean.sayHello();
	}


輸出結果:3:Hello Jane!

3. 使用例項工場方法

先定義例項工廠Bean

<bean id="instanceFactoryBean" class="InstanceFactory全類名"/>

再使用例項工廠Bean建立我們需要的Bean,注意這裡沒有class屬性了。若要傳入指定方法引數,則和使用構造器方式一樣。
<bean id="fourthBean" factory-bean="instanceFactoryBean" factory-method="newInstance"> </bean>

例子

例項工廠類HelloApiInstanceFactory.java

package com.szse.beans;

public class HelloApiInstanceFactory {
	public HelloApi newInstance(int num,String message) {
		   return new HelloApiImpl(num,message);
	   }
}

xml檔案中加入

<bean id="instanceFactoryBean" class="com.szse.beans.HelloApiInstanceFactory"/>
<bean id="fourthBean" factory-bean="instanceFactoryBean" factory-method="newInstance">  
	<constructor-arg name="num" value="4" />
	<constructor-arg name="message" value="Hello Tom!" />
</bean>

測試方法testInstantiatingBeanByFactory加入

HelloApi fourthBean = ctx.getBean("fourthBean", HelloApi.class);
fourthBean.sayHello();
輸出結果 4:Hello Tom!

這三種例項化Bean的方式只是配置不一樣,從獲取方式看完全一樣。這三種方式都是基於XML配置檔案,脫離xml檔案

Spring容器還有基於註解(Annotation)的方式來建立Bean,這個我們以後會講到。