在沒有IOC容器的狀況下,若是咱們須要某個類具體的操做以下所示:java
傳統的Bean建立git
首先在這裏強調一下IOC不是Spring提出來了,在Spring以前就已經有人提出了IOC思想,只不過在Spring以前都是偏理論化沒有一個具體的落地方案,Spring在技術層面把IOC思想體現的淋漓盡致。程序員
從上圖可知:github
在理解控制反轉以前咱們首先要清楚控制是指什麼? 反轉又反轉了什麼?面試
將到IOC確定會有人想到DI(Dependancy Injection)依賴注入,那這二者有什麼不一樣和相同呢?spring
<?xml version="1.0" encoding="UTF-8" ?> <!--跟標籤beans,裏面配置一個又一個的bean子標籤,每個bean子標籤都表明一個類的配置--> <beans> <!--id標識對象,class是類的全限定類名--> <bean id="orderDao" class="com.customize.spring.dao.impl.OrderDaoImpl"> </bean> <bean id="stockDao" class="com.customize.spring.dao.impl.StockDaoImpl"> </bean> <bean id="orderService" class="com.customize.spring.service.impl.OrderServiceImpl"> <!--經過set方法注入--> <property name="setOrderDao" ref="orderDao"></property> <property name="setStockDao" ref="stockDao"></property> </bean> </beans>
public class BeanFactory { /** * 存放對象 */ private static Map<String, Object> map = new ConcurrentHashMap<>(); /** * 對外提供的接口 * @param id * @return */ public static Object getBean(String id) { return map.get(id); } static { // 只加載一次就是在BeanFactory初始化的時候去加載類 // 任務一:讀取解析xml,經過反射技術實例化對象而且存儲待用(map集合) System.out.println("開始加載Bean對象"); // 加載xml InputStream resourceAsStream = BeanFactory.class.getClassLoader().getResourceAsStream("beans.xml"); // 解析xml SAXReader saxReader = new SAXReader(); try { Document document = saxReader.read(resourceAsStream); Element rootElement = document.getRootElement(); List<Element> beanList = rootElement.selectNodes("//bean"); for (int i = 0; i < beanList.size(); i++) { Element element = beanList.get(i); // 處理每一個bean元素,獲取到該元素的id 和 class 屬性 String id = element.attributeValue("id"); String clazz = element.attributeValue("class"); // 經過反射技術實例化對象 Class<?> aClass = Class.forName(clazz); Object o = aClass.newInstance(); // 存儲到map中待用 map.put(id,o); } // 實例化完成以後維護對象的依賴關係,檢查哪些對象須要傳值進入,根據它的配置,咱們傳入相應的值 // 有property子元素的bean就有傳值需求 List<Element> propertyList = rootElement.selectNodes("//property"); // 解析property,獲取父元素 for (int i = 0; i < propertyList.size(); i++) { Element element = propertyList.get(i); String name = element.attributeValue("name"); String ref = element.attributeValue("ref"); // 找到當前須要被處理依賴關係的bean Element parent = element.getParent(); // 調用父元素對象的反射功能 String parentId = parent.attributeValue("id"); Object parentObject = map.get(parentId); // 遍歷父對象中的全部方法,找到set方法 Method[] methods = parentObject.getClass().getMethods(); for (int j = 0; j < methods.length; j++) { Method method = methods[j]; // 該方法就是 set方法 if(method.getName().equalsIgnoreCase(name)) { method.invoke(parentObject,map.get(ref)); } } // 把處理以後的parentObject從新放到map中 map.put(parentId,parentObject); } System.out.println("加載完畢,Map中的Bean對象個數爲:" + map.size()); } catch (Exception e) { e.printStackTrace(); } } }
public class OrderServiceImpl implements OrderService { private OrderDao orderDao; private StockDao stockDao; public void setOrderDao(OrderDao orderDao) { this.orderDao = orderDao; } public void setStockDao(StockDao stockDao) { this.stockDao = stockDao; } @Override public void order(Order order) { // 沒有IOC容器的狀況下 // OrderDao orderDao = new OrderDaoImpl(); // // 保存訂單 // orderDao.save(order); // // //扣除庫存 // StockDao stockDao = new StockDaoImpl(); // stockDao.subStock(order.getName()); // 有IOC容器的基礎上 orderDao.save(order); //扣除庫存 stockDao.subStock(order.getName()); System.out.println("下單成功"); } }
測試ide