SpringIoc 和 工廠模式(反射實現)


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

 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 }
View Code

問題:若增加新水果,如香蕉,則工廠類也要修改.

解決: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 }
View Code

問題:創建實例時,需要提供“完整的類名”

1 public class FactoryDemo2 {
2     public static void main(String args[]) {
3         Fruit f = Factory.getInstance("org.Orange");
4         f.eat();
5     }
6 }
View Code

解決:增加“配置文件”優化.

三、增加“配置文件”:

 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 } 
View Code
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 }
View Code

通過配置文件,可以控制程序的執行,現在看起來有點像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 }
View Code
 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 }
View Code

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>  
View Code

測試類

 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 }
View Code

 

對比前面的那個“Fruit程序”,你會發現,spring配置文件,還是一個工廠(只是換種形式一樣),它管理所有的類,新建的類要到工廠里面去登記,不然就不能被主程序用,這就是為什么說ioc就是工廠模式的升級版。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM