工廠模式是你們很是熟悉的設計模式,spring BeanFactory將此模式發揚光大,今天就來說講,spring IOC容器是如何幫我管理Bean,構造對象的,簡單的寫了一個demo。java
思路以下:spring
關於什麼是工廠模式以前寫過一個:http://www.javashuo.com/article/p-fbilqccu-ek.html設計模式
package com.spring.xml; public interface Pizza{ public float getPrice(); }
package com.spring.xml; public class MargheritaPizza implements Pizza{ public float getPrice() { System.out.println("8.5f"); return 8.5f; } }
public class CalzonePizza implements Pizza{ public float getPrice() { System.out.println("2.5f"); return 2.5f; } }
經過傳入參數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); } }
package com.spring.xml; 2 3 public interface BeanFactory { 4 Object getBean(String id); 5 }
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); } }
<?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