别急接下来就是细讲我们常说的控制反转控制反转在理解控制反转之前我们首先要清楚控制是指什么?反转又反转了什么?1. 控制: 指的就是我们上述说的我们失去的权利(创建对象的创建,或者说控制对象的权利)2. 反转: 指的是控制权的转变在没有IOC的容器上我们程序员想创建谁就创建谁的权利在IOC容器下程序员就只能委屈巴巴的向IOC容器索取对象创建对象的权利由程序员到IOC容器手里了IOC解决了什么问题?其实就是解决了对象之间的耦合问题我们不需要在通过New关键字来创建对象,而是从容器中获取达到一种松耦合的目的同时IOC容器也方便管理容器内的所有Bean对象所谓的Bean的生命周期IOC和DI的区别将到IOC肯定会有人想到DI(Dependancy Injection)依赖注入,那这两者有什么不同和相同呢?相同点IOC和DI描述的都是同一件事情(对象的实例化以及维护对象与对象已经的依赖关系)不同点首先IOC是一种思想,而DI是一种具体的技术实现手段IOC是站着对象的角度上对象的实例化以及管理从程序员的手里交给了IOC容器DI是站着容器的角度的上会把对象的依赖的其他对象注入到容器中,上述案例中的A类依赖B类IOC容器不仅仅将A类放到容器中还需要将其依赖的B类也一并加载到IOC容器中如何自定义实现一个IOC容器小伙伴们看到这里其实对IOC容器已经有了一定的了解那如果在面试的过程中面试官问你如何实现一个自定义的IOC容器你可以讲出的具体思路嘛?可以先想一想在继续往下看,看看是不是和自己的想发不谋而合思路大致如下所示:想必大家都有自己的一定的理解,可能做法比较简单,但是对于理解IOC容器而已其实已经足够了如果想更加准确或者深入了解其底层实现,可以按照这个思路去看Spring的相关源码实现,相信你一定会得心应手小案例我们通过一个小案例来写我们的IOC容器我们经常购物,我们可以把购物简单的理解成下单和减库存两个操作有同学会问为什么要写这个案例啊,不仅为了我们能够理解IOC容器也为了我们后续的文章将AOP和AOP的经典实现事务控制铺垫的Coding首先整体的代码结构很简单,在这里也说明一下Bean的配置文件
<?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>
创建Bean对象”工厂“进行创建主要就是读取xml,通过set方法传值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对象\");// 加载xmlInputStream resourceAsStream = BeanFactory.class.getClassLoader.getResourceAsStream(\"beans.xml\");// 解析xmlSAXReader 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\");// 找到当前需要被处理依赖关系的beanElement parent = element.getParent;// 调用父元素对象的反射功能String parentId = parent.attributeValue(\"id\");Object parentObject = map.get(parentId);// 遍历父对象中的所有方法,找到\"set\" + nameMethod methods = parentObject.getClass.getMethods;for (int j = 0; j < methods.length; j++) {Method method = methods[j];// 该方法就是 setAccountDao(AccountDao accountDao)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;}@Overridepublic 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(\"下单成功\");}}
启动测试地址: http://localhost:9080/order?userId=857&name=ipone配图:项目地址项目地址:https://github.com/SuperEngCoding/super-spring/有帮忙到你记得点个小星星哦本文作者「后端学长」,欢迎关注作者的微信订阅号「后端学长」-END-如果看到这里,说明你喜欢这篇文章,请 转发、点赞同时 标星(置顶)本公众号可以第一时间接受到博文推送1. 肝了一个月这本 Java 开发手册出炉啦
深入理解 Mybatis 插件开发3.互联网大厂的后端技术栈强烈推荐 16 款 IDEA 插件最近整理一份面试资料《Java技术栈学习手册》,覆盖了Java技术、面试题精选、Spring全家桶、Nginx、SSM、微服务、数据库、数据结构、架构等等
(图片来源网络,侵删)
0 评论