spring依赖注入原理详解----转载

  • 所谓依赖注入就是指:在运行期,由外部容器动态地将依赖对象注入到组件中。当spring容器启动后,spring容器初始化,创建并管理bean对象,以及销毁它。所以我们只需从容器直接获取Bean对象就行,而不用编写一句代码来创建bean对象。这种现象就称作控制反转,即应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责的。这样控制权就由应用转移到了外部容器,控制权的转移就是所谓反转。虽然平时只需要按要求将bean配置到配置文件中,但是了解其实现过程对理解spring的实现原理是有好处的,下面就是模拟spring实现依赖注入的过程。
  • 首先最简单的就是模拟创建bean实例,实现这个过程需要几个辅助类和辅助方法。有一个最重要的辅助方法就是读取XML的配置,可以利用DOM4J来实现对配置文件的读取,这里假设已经读取到一个List对象beanDefines中去了。读取配置后就需要将读取到的代表一个bean的信息放到一个对象中。这个对象的类就是BeanDefinition(包括id、className和一个装PropertyDefinition对象的List),还一个辅助类就是属性值对象的类PropertyDefinition(包括name属性和ref属性,都是字符串,属性名字和配置文件中的属性名字一致)。这两个辅助类就是普通JavaBean对象,都有getter和setter方法。
// An highlighted blockfor(BeanDefinition beanDefinition : beanDefines){if(beanDefinition.getClassName()!=null && !"".equals(beanDefinition.getClassName().trim()))sigletons.put(beanDefinition.getId(), Class.forName(beanDefinition.getClassName()).newInstance());}
  • 如上所示,通过一个for循环对beanDefines进行循环遍历,如果其中的某个BeanDefinition具有正确的类名,怎通过Class.forName创建该类的字节码对象,然后通过newInstance方法创建一个调用默认构造函数
  • 创建出来的对象,然后放入名字为sigletons的Map对象中,它的key是bean定义的id属性的值。以上代码省略了try-catch块和其它相关的定义。从这里可以看出,spring初始化bean时,首先是从配置文件中获取bean的定义信息,然后在通过某种方式创建实例对象。
    创建一个bean的实例出来还只是依赖注入的一小部分前提工作,而最重要的属性还没有被注入到相应的对象中。下面就是一为bean对象注入相应属性值的关键代码,其中分了两种情况注入,一种是通过ref属性注入的,还有一种是经过value属性注入的简单属性(为了注入简单属性,在读取xml配置的时候,也保存属性为value的值,因此propertyDefinition中增加了value属性,用来存储对应的值):
// An highlighted blockfor(BeanDefinition beanDefinition : beanDefines){Object bean = sigletons.get(beanDefinition.getId());if(bean!=null){try {PropertyDescriptor[] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();for(PropertyDefinition propertyDefinition : beanDefinition.getPropertys()){for(PropertyDescriptor properdesc : ps){if(propertyDefinition.getName().equals(properdesc.getName())){Method setter = properdesc.getWriteMethod();if(setter!=null){Object value = null;if(propertyDefinition.getRef()!=null && !"".equals(propertyDefinition.getRef().trim())){value = sigletons.get(propertyDefinition.getRef());}else{value = ConvertUtils.convert(propertyDefinition.getValue(), properdesc.getPropertyType());}setter.setAccessible(true);setter.invoke(bean, value);}break;}}}} catch (Exception e) {}}}
  • 上面代码中最外层的for循环是依次将属性的值注入进从xml中读取并实例化的bean对象中。下面来分析循环中的一个:首先从集合beanDefines拿出一个BeanDefinition对象,接着从存储实例化的bean对象的Map对象sigletons中取得bean的引用。因为存储bean的key是相应beanDefinition中的id属性,所以可以很简单的通过这个id的值找到对应的实例化的bean对象(此时还为注入任何属性)。程序严谨一点就先判断一下bean是否为空,因为师为bean注入属性,当然先保证它自身的存在。有了bean的实例对象后,就可以跟据bean的字节码码对象生成该bean的属性描述数组ps,这是利用工具类Introspector办到的。然后开始遍历从配置文件读取的bean的定义对象beanDefinition,从中获取某一个属性的描述对象。接下来的关键就是再次通过一个for循环遍历ps的属性描述数组,找到与前面从beanDefinition中获取的属性描述对象名字相同的属性的名字,找到后,通过该ps对象中的属性描述对象利用反射获取setter方法(Method setter = properdesc.getWriteMethod())。简单点说,就是以properdesc的name为依据,去beanDefinition里的属性描述对象里找着相同名字的属性定义对象。如果找到就可以开始执行注入功能了,在这里就可以判断该属性定义对象的ref属性有值还是value对象的值存在,如果是ref,就可以从spring中bean的Map容器找ref属性值的bean对象,如果是value属性的定义,就调用ConvertUtils工具类中的convert方法,将value值转换成bean的属性的类型。最后就是设置setter方法的可访问性(准确的说就是为了能够访问私有的方法),然后利用反射在相应的bean上调用该方法。
    通过上述分析,发现依赖注入的实现并不是很困难。当然spring的实现是不可能这么简单那和粗糙的,但是至少说明了依赖注入的一种实现方式,让依赖注入不在那么抽象和遥不可及。这就是传智播客特有特点,对知识点的讲解非常深入,让学员知其然也知其所以然,这样在以后编写代码过程中很少有迷惑的地方,也能编写出更健壮和优雅的代码。

转载于:https://www.cnblogs.com/zhaoxd/archive/2013/05/14/3077790.html

spring依赖注入原理详解(转载)相关推荐

  1. spring依赖注入原理详解

    所谓依赖注入就是指:在运行期,由外部容器动态地将依赖对象注入到组件中.当spring容器启动后,spring容器初始化,创建并管理bean对象,以及销毁它.所以我们只需从容器直接获取Bean对象就行, ...

  2. Spring 依赖注入方式详解

    平常的Java开发中,程序员在某个类中需要依赖其它类的方法. 通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理. Spring提出了依赖注入的思想,即依赖类不由 ...

  3. spring依赖注入原理(转载)

    关于spring依赖注入原理的文章在网络上已经有很多,我要写的这篇文章原文出自http://taeky.iteye.com/blog/563450,只所以再一次写下来只是为了一为自己收藏,方便以后的复 ...

  4. Java程序员进阶——Spring依赖注入原理分析

    Spring依赖注入原理分析 下面谈谈Spring是如何实现反转模式IOC或依赖注入模式DI: 平时,我们需要生成一个对象,使用new语法,如一个类为A public class A{public v ...

  5. Spring的注入方式详解

    [html] view plaincopy Spring的注入方式详解 Spring有三个注入方式,type1,type2,type3 type1  接口依赖 type2  setter/getter ...

  6. Web网络安全漏洞分析,SQL注入原理详解

    本文主要为大家介绍了Web网络安全漏洞分析SQL注入的原理详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪 一.SQL注入的基础 1.1 介绍SQL注入 SQL注入就是 ...

  7. Java程序员从笨鸟到菜鸟之(一百)sql注入攻击详解(一)sql注入原理详解

    前段时间,在很多博客和微博中暴漏出了12306铁道部网站的一些漏洞,作为这么大的一个项目,要说有漏洞也不是没可能,但其漏洞确是一些菜鸟级程序员才会犯的错误.其实sql注入漏洞就是一个.作为一个菜鸟小程 ...

  8. VLAN原理详解[转载] 网桥--交换机---路由器

    来自:http://blog.csdn.net/phunxm/article/details/9498829 一.什么是桥接   桥接工作在OSI网络参考模型的第二层数据链路层,是一种以MAC地址来作 ...

  9. cookie注入原理详解

    那我们还是围绕以下几个问题来看看cookie注入: 1.什么是cookie注入? 2.为什么要cookie注入? 3.怎样cookie注入? 1.什么是cookie注入? ♦cookie注入的原理是: ...

最新文章

  1. CSDN送会员?免费的!都来领!
  2. h计算机二级基础知识题库,计算机二级考试试题
  3. 浅析高端网站建设策划方案都包括哪些内容?
  4. bzoj2161 布娃娃
  5. BZOJ-2756 奇怪的游戏 黑白染色+最大流+当前弧优化+二分判断+分类讨论
  6. 一张纸折多少次可以变成珠穆朗玛峰那么高?
  7. 4,GIL全局解释器锁,event事件,信号量
  8. leetcood学习笔记-112-路径总和
  9. 用C#制作PDF文件全攻略 (专至csdn)
  10. 系统架构师复习-操作系统
  11. OpenCV-标准霍夫变换cv::HoughLines
  12. python函数定义中参数列表里的参数是_python-函数(def)参数 及参数解构 变量 知识整理...
  13. 几种常见的微服务架构方案——ZeroC IceGrid、Spring Cloud、基于消息队列、Docker Swarm
  14. CHARINDEX 连同 SUBSTRING 对字符串删除处理...
  15. MUSIC算法的参数设置
  16. 2021数学建模学习笔记
  17. 收集的vue各种库,UI库等
  18. XML文件里处理大于号小于号方式
  19. Git-Dumper工具:从站点中导出一个Git库
  20. 购物车(session版)

热门文章

  1. Shardingsphere 强制主库查询
  2. cytoscape使用方法_Cytoscape使用方法
  3. 【负载均衡集群——保姆式教学】
  4. LivePlayer H5直播/点播播放器安装与使用
  5. 第一个简单的程序——吃货联盟系统
  6. 技术人员谈管理之九大项目管理记忆口诀
  7. 大班幼儿告状行为与教师教育态度和方法的研究
  8. 全球有多少C++、Java、PHP、Python程序员?
  9. 如何从Windows中访问EXT4格式的Linux硬盘
  10. 魅族m8android固件,魅族M8刷Android系统图文详细教程