一、先演示 “簡單工廠”:

1 package org; 2 3 interface Fruit { 4 public void eat(); 5 } 6 7 class Apple implements Fruit { 8 public void eat() { 9 System.out.println("吃蘋果。"); 10 } 11 } 12 13 class Orange implements Fruit { 14 public void eat() { 15 System.out.println("吃橘子"); 16 } 17 } 18 19 class Factory { // 工廠類 20 public static Fruit getInstance(String className) { 21 Fruit f = null; 22 if (className.equals("apple")) { 23 f = new Apple(); 24 } 25 if (className.endsWith("orange")) { 26 f = new Orange(); 27 } 28 return f; 29 } 30 } 31 32 public class FactoryDemo { 33 public static void main(String args[]) { 34 Fruit f = Factory.getInstance("apple"); 35 f.eat(); 36 } 37 }
問題:若增加新水果,如香蕉,則工廠類也要修改.
解決:java的反射機制.
二、修改“工廠類”:

1 //工廠類(修改) 2 class Factory { 3 public static Fruit getInstance(String className) { 4 Fruit f = null; 5 try { 6 f = (Fruit) Class.forName(className).newInstance(); 7 } catch (Exception e) { 8 e.printStackTrace(); 9 } 10 return f; 11 } 12 }
問題:創建實例時,需要提供“完整的類名”

1 public class FactoryDemo2 { 2 public static void main(String args[]) { 3 Fruit f = Factory.getInstance("org.Orange"); 4 f.eat(); 5 } 6 }
解決:增加“配置文件”優化.
三、增加“配置文件”:

1 class PropertiesOperate{ 2 private Properties pro=null; 3 private File file=new File("d:"+File.separator+"fruit.properties"); 4 5 public PropertiesOperate(){ 6 pro=new Properties(); 7 if(file.exists()){ 8 try { 9 pro.loadFromXML(new FileInputStream(file)); 10 } catch (Exception e) { 11 e.printStackTrace(); 12 } 13 }else{ 14 this.save(); 15 } 16 } 17 private void save(){ 18 pro.setProperty("apple","org.Apple"); 19 pro.setProperty("orange", "org.Orange"); 20 try { 21 pro.storeToXML(new FileOutputStream(this.file),"Fruit"); 22 } catch (Exception e) { 23 e.printStackTrace(); 24 } 25 } 26 public Properties getProperties(){ 27 return pro; 28 } 29 }

1 public class FactoryDemo3 { 2 public static void main(String args[]) { 3 Properties pro=new PropertiesOperate().getProperties(); 4 Fruit f= Factory.getInstance(pro.getProperty("orange")); 5 f.eat(); 6 } 7 }
通過配置文件,可以控制程序的執行,現在看起來有點像spring的ioc了。
該程序使用了工廠模式,把所有的類放在一個Factory里面,而為了動態的管理這些類(即使增加了新的Fruit類,這個工廠也不用變化),就用了java的反射機制。
另外,通過配置文件,使得一長串完整的類名稱(如org.Apple)可用任意簡短的名稱來代替(如apple)。
四、簡單的spring配置文件測試

1 package test; 2 3 public class Person { 4 private String name; 5 private int age; 6 private Grade grade; 7 8 public String getName() { 9 return name; 10 } 11 12 public Grade getGrade() { 13 return grade; 14 } 15 16 public void setGrade(Grade grade) { 17 this.grade = grade; 18 } 19 20 public void setName(String name) { 21 this.name = name; 22 } 23 24 public void setAge(int age) { 25 this.age = age; 26 } 27 28 public int getAge() { 29 return age; 30 } 31 32 public int getTotleGrade() { 33 return grade.getEnglish() + grade.getMath(); 34 } 35 }

1 package test; 2 3 public class Grade { 4 private int math; 5 private int english; 6 7 public int getMath() { 8 return math; 9 } 10 11 public void setMath(int math) { 12 this.math = math; 13 } 14 15 public int getEnglish() { 16 return english; 17 } 18 19 public void setEnglish(int english) { 20 this.english = english; 21 } 22 }
bean .xml 類

1 <?xml version="1.0" encoding="UTF-8"?> 2 3 <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" 4 5 "http://www.springframework.org/dtd/spring-beans.dtd"> 6 <beans> 7 <bean id="Person" class="test.Person"><!-- 第一個bean,是一個Person類,id名字隨便取,還要寫上類的全名 --> 8 <property name="name"> 9 <value>小龍</value><!-- 這里的名字是通過程序里面的set來賦值的,如果去掉程序對應的set,就出錯了 --> 10 </property> 11 <property name="age"> 12 <value>23</value> 13 </property> 14 <property name="grade"><!-- 這里有點特別,這個grade變量是一個對象,和一般的變量要區別對待 --> 15 <ref local="Grade"/><!-- 這里指向了本配置文件里面一個名字叫Grade(即id=Grade)的bean --> 16 </property> 17 </bean> 18 <bean id="Grade" class="test.Grade"><!-- 同上 --> 19 <property name="math"> 20 <value>99</value> 21 </property> 22 <property name="english"> 23 <value>59</value> 24 </property> 25 </bean> 26 </beans>
測試類

1 package test; 2 3 import org.springframework.beans.factory.BeanFactory; 4 import org.springframework.beans.factory.xml.XmlBeanFactory; 5 import org.springframework.core.io.ClassPathResource; 6 import org.springframework.core.io.Resource; 7 8 public class Test { 9 public static void main(String args[]){ 10 Resource input = new ClassPathResource("test/Bean.xml");//Bean.xml的路徑 11 12 System.out.println("resource is:" + input); 13 14 BeanFactory factory = new XmlBeanFactory(input);//把input扔到工廠里面去,這個工廠就能為你提供實例了(我也不知道能不能這樣說) 15 16 Person person =(Person) factory.getBean("Person");//你要一個叫Person的東西,那好,工廠就去找“Person"給你 17 Grade grade=(Grade)factory.getBean("Grade"); 18 System.out.println("姓名:"+person.getName());//person可以調用里面相關的方法,就相當於new了一個Person一樣 19 System.out.println("年齡:"+person.getAge()); 20 System.out.println("數學成績:"+grade.getMath()); 21 System.out.println("英語成績:"+grade.getEnglish()); 22 System.out.println("數學,英語總成績:"+person.getTotleGrade()); 23 } 24 }
對比前面的那個“Fruit程序”,你會發現,spring配置文件,還是一個工廠(只是換種形式一樣),它管理所有的類,新建的類要到工廠里面去登記,不然就不能被主程序用,這就是為什么說ioc就是工廠模式的升級版。