1. 程式人生 > >spring通過工廠方法和FactoryBean來配置Bean

spring通過工廠方法和FactoryBean來配置Bean

spring通過工廠方法配置Bean

1.通過呼叫靜態工廠方法建立bean(直接呼叫某一個類的靜態方法就可以返回bean的例項)

呼叫靜態工廠方法建立Bean是將物件建立的過程封裝到靜態方法中,當客戶端需要物件時,只需要簡單的呼叫靜態方法, 而不關心建立物件的細節。
要宣告通過靜態方法建立bean:    1.需要在bean的class屬性裡指定擁有該方法的類,    2.同時在factory-method屬性裡指定工廠方法的名稱,    3.最後,使用<constrctor-arg>元素為該方法傳遞方法引數。
	<!--
	            通過靜態工廠方法來配置bean,注意不是配置靜態工廠方法例項,而是bean例項,
		且注意對應類是包含靜態工廠方法的類
		class屬性:指向靜態工廠方法的全類名
		factory-method:指向靜態工廠方法中的名字
		constructor-arg:如果某工廠方法需要傳入引數,則使用constructor-arg來配置引數
		-->
	<bean id="car1"
	   class="com.wul.spring.bean.factory.StaticCarFactory"
	   factory-method="getCar">
	   <constructor-arg value="audi"></constructor-arg>
	</bean>

2.通過呼叫例項工廠方法建立bean(即先需要建立工廠bean本身,再呼叫工廠的例項方法來返回bean的例項)

例項工廠方法:將物件的建立過程封裝到另外一個物件例項方法裡,當客戶端需要請求物件時,只需要簡單的呼叫該例項方法而不需要關心物件的建立細節。
  1.先宣告例項工廠類的bean 宣告通過例項工廠方法建立的bean:   2.在bean的factory-bean屬性裡指定擁有該該工廠方法的bean   3.在factory-method屬性裡指定該工廠方法的名稱。
  4.使用constructor-arg元素為工廠方法傳遞方法引數。
	<!-- 1.配置工廠的例項 -->
	<bean id="carFactory" 
	      class="com.wul.spring.bean.factory.InstanceCarFactory"></bean>
	<!-- 
		2.通過例項工廠來配置bean   
			class屬性:指向例項工廠方法的全類名
			factory-method:指向例項工廠方法的名字
			constructor-arg:如果工廠方法需要傳入引數,則使用constructor-arg來配置引數
	--> 
	 <bean id="car2" factory-bean="carFactory"
	      factory-method="getCar">
	      <constructor-arg value="ford"></constructor-arg>
	 </bean>

3.spring通過FactoryBean配置

當配置的bean裡需要引用其他的bean------------通過FactoryBean配置是最好的方式

1.自定義的Factory需要實現FactoryBean介面
public class CarFactoryBean implements FactoryBean<Car>{

	private String brand;
	
	public void setBrand(String brand) {
		this.brand = brand;
	}
	
	//返回bean的物件
	@Override
	public Car getObject() throws Exception {
		return new Car(brand,500000);
	}
	
	//返回的bean的型別
	@Override
	public Class<?> getObjectType() {
		// TODO Auto-generated method stub
		return Car.class;
	}
	
	//是否是單例的
	@Override
	public boolean isSingleton() {
		// TODO Auto-generated method stub
		return true;
	}

}


2.配置bean
<!-- 	
             通過FactoryBean來配置Bean的例項
	class:指向FactoryBean的全類名
	property:配置FactoryBean的屬性 
	
	注意:實際返回的例項是FactoryBean的getObject()方法返回的例項
-->
	<bean id="car1"
		class="com.wul.spring.bean.factoryBean.CarFactoryBean">
		<property name="brand" value="BMW"></property>
	</bean>


下面給出示例:

spring通過工廠方法配置Bean:

Car.java
package com.wul.spring.bean.factory;

public class Car {
	
	private String brand;
	
	private double price;

	public String getBrand() {
		return brand;
	}

	public void setBrand(String brand) {
		this.brand = brand;
	}

	public double getPrice() {
		return price;
	}

	public void setPrice(double price) {
		this.price = price;
	}

	@Override
	public String toString() {
		return "Car [brand=" + brand + ", price=" + price + "]";
	}

	public Car(String brand, double price) {
		super();
		this.brand = brand;
		this.price = price;
	}
	
	
}
StaticCarFactory.java
package com.wul.spring.bean.factory;

import java.util.HashMap;
import java.util.Map;


/*靜態工廠方法:直接呼叫某一個類的靜態方法就可以返回Bean的例項*/
public class StaticCarFactory {
	
	private static Map<String , Car> cars = new HashMap<String,Car>();
	
	static{
		cars.put("audi", new Car("Audi",300000));
		cars.put("ford", new Car("Ford",400000));
	}
	
	//靜態工廠方法,不需要建立StaticCarFactory物件情況下,通過該方法可以得到對應例項。
	public static Car getCar(String brand){	
		return cars.get(brand);
	}
}


InstanceCarFactory.java
package com.wul.spring.bean.factory;

import java.util.HashMap;
import java.util.Map;

/*
 * 例項工廠方法:例項工廠的方法,即先需要建立工廠bean本身,再呼叫工廠的例項方法來
 *       返回bean的例項
 */
public class InstanceCarFactory {
	
	private Map<String,Car> cars = null;
	
	public InstanceCarFactory(){
		cars = new HashMap<String,Car>();
		cars.put("audi", new Car("Audi",300000));
		cars.put("ford", new Car("Ford",400000));
	}
	
	public Car getCar(String brand){
		return cars.get(brand);
	}
}
bean-factory.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.xsd">

	<!--
	            通過靜態工廠方法來配置bean,注意不是配置靜態工廠方法例項,而是bean例項,
		且注意對應類是包含靜態工廠方法的類
		class屬性:指向靜態工廠方法的全類名
		factory-method:指向靜態工廠方法中的名字
		constructor-arg:如果某工廠方法需要傳入引數,則使用constructor-arg來配置引數
		-->
	<bean id="car1"
	   class="com.wul.spring.bean.factory.StaticCarFactory"
	   factory-method="getCar">
	   <constructor-arg value="audi"></constructor-arg>
	</bean>
	
	<!-- 1.配置工廠的例項 -->
	<bean id="carFactory" 
	      class="com.wul.spring.bean.factory.InstanceCarFactory"></bean>
	<!-- 
		2.通過例項工廠來配置bean   
			class屬性:指向例項工廠方法的全類名
			factory-method:指向例項工廠方法的名字
			constructor-arg:如果工廠方法需要傳入引數,則使用constructor-arg來配置引數
	--> 
	 <bean id="car2" factory-bean="carFactory"
	      factory-method="getCar">
	      <constructor-arg value="ford"></constructor-arg>
	 </bean>  
	
</beans>


Mainfactory.java
package com.wul.spring.bean.factory;

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

public class Mainfactory {
	public static void main(String[] args) {
		
		ApplicationContext ctx = new ClassPathXmlApplicationContext("bean-factory.xml");
		
		//靜態工廠方法測試:
		Car car1 = (Car) ctx.getBean("car1");
		System.out.println(car1);
		
		//例項工廠方法測試:
		Car car2 = (Car) ctx.getBean("car2");
		System.out.println(car2);
	}
}

通過FactoryBean來配置Bean

Car.java(同上)
CarFactoryBean.java
package com.wul.spring.bean.factoryBean;

import org.springframework.beans.factory.FactoryBean;

//自定義的Factory需要實現FactoryBean介面
public class CarFactoryBean implements FactoryBean<Car>{

	private String brand;
	
	public void setBrand(String brand) {
		this.brand = brand;
	}
	
	//返回bean的物件
	@Override
	public Car getObject() throws Exception {
		return new Car(brand,500000);
	}
	
	//返回的bean的型別
	@Override
	public Class<?> getObjectType() {
		// TODO Auto-generated method stub
		return Car.class;
	}
	
	//是否是單例的
	@Override
	public boolean isSingleton() {
		// TODO Auto-generated method stub
		return true;
	}

}

bean-factorybean.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.xsd">

	
<!-- 	
             通過FactoryBean來配置Bean的例項
	class:指向FactoryBean的全類名
	property:配置FactoryBean的屬性 
	
	注意:實際返回的例項是FactoryBean的getObject()方法返回的例項
-->
	<bean id="car1"
		class="com.wul.spring.bean.factoryBean.CarFactoryBean">
		<property name="brand" value="BMW"></property>
	</bean>

</beans>

MainFactoryBean.java
package com.wul.spring.bean.factoryBean;

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

public class MainFactoryBean {
	
	public static void main(String[] args) {
		ApplicationContext ctx = new ClassPathXmlApplicationContext("bean-factorybean.xml");
		
		Car car = (Car) ctx.getBean("car1");
		System.out.println(car);
		
	}
}