spring BeanFactory的xml工廠模式簡單實現(二)

背景

工廠模式是你們很是熟悉的設計模式,spring BeanFactory將此模式發揚光大,今天就來說講,spring IOC容器是如何幫我管理Bean,構造對象的,簡單的寫了一個demo。java

思路以下:spring

  1. 解析xml文件,將bean標籤的,id,class存儲在一個map中
  2. 獲取實例對象時經過id匹配,匹配成功返回該對象

先看下常見的工廠模式

關於什麼是工廠模式以前寫過一個:http://www.javashuo.com/article/p-fbilqccu-ek.html設計模式

建立一個接口類Pizza

package com.spring.xml;

public interface Pizza{
    public float getPrice();
}

MargheritaPizza 類

package com.spring.xml;

public class MargheritaPizza implements Pizza{
    public float getPrice() {
        System.out.println("8.5f");
        return 8.5f;
       
    }
}

CalzonePizza 類

public class CalzonePizza implements Pizza{
   public float getPrice() {
       System.out.println("2.5f");
       return 2.5f;
   }
   

}

創建工廠類PizzaFactory

經過傳入參數id,選擇不一樣的實例類,若是後續不斷的增長新類,會頻繁的修改create方法,不符合開閉原則app

public class PizzaFactory {
    public Pizza create(String id) {
        if (id == null) {
          throw new IllegalArgumentException("id is null!");
        }
        if ("Calzone".equals(id)) {
          return new CalzonePizza();
        }

        if ("Margherita".equals(id)) {
          return new MargheritaPizza();
        }

        throw new IllegalArgumentException("Unknown id = " + id);
      }

}

採用spring xml 配置的方式實現工廠類的管理

創建一個BeanFactory接口

package com.spring.xml;
2 
3 public interface BeanFactory {
4     Object getBean(String id);
5 }

實現類ClassPathXmlApplicationContext.java

BeanFactory實現類,主要功能是解析xml文件,封裝bean到map中dom

public class ClassPathXmlApplicationContext implements BeanFactory {
     private Map<String, Object> beans = new HashMap<String, Object>();
     public ClassPathXmlApplicationContext(String fileName) throws Exception{
         SAXReader reader = new SAXReader();
         Document document =     reader.read(this.getClass().getClassLoader().getResourceAsStream(fileName));
         List<Element> elements = document.selectNodes("/beans/bean");
        for (Element e : elements) {
           //獲取beanId
            String id = e.attributeValue("id");
           //獲取beanId對於的ClassPath下class全路徑名稱
             String value = e.attributeValue("class");
            //經過反射實例化該beanId 的class對象
            Object o = Class.forName(value).newInstance();
            //封裝到一個Map裏
             beans.put(id, o);
         }
     }
     
     public Object getBean(String id) {
         return beans.get(id);
    }
 
 }

applicationContext.xml配置

<?xml version="1.0" encoding="UTF-8"?>
 <beans>
     <bean id="calzone" class="com.spring.xml.CalzonePizza"></bean>
      <bean id="margherita" class="com.spring.xml.MargheritaPizza"></bean>
 </beans>

寫一個類測試一下測試

package com.spring.xml;
 
 import org.dom4j.DocumentException;
 
 public class Test {

    public static void main(String[] args) throws Exception {
         BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
         Pizza p = (Pizza)factory.getBean("Calzone");
         p.getPrice();
        
     }
 
}

看完代碼應該很是清楚,比起原先經過if else來選擇不一樣的實現類方便。this

相關文章
相關標籤/搜索