在没有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