基于XML的依赖注入
1、依赖注入发生的时间
当 Spring IOC 容器完成了 Bean 定义资源的定位、载入和解析注册以后,IOC 容器中已经管理类 Bean 定义的相关数据,但是此时 IOC 容器还没有对所管理的 Bean 进行依赖注入,依赖注入在以下两种情况 发生:
(1).用户第一次通过 getBean 方法向 IOC 容索要 Bean 时,IOC 容器触发依赖注入。
(2).当用户在 Bean 定义资源中为元素配置了 lazy-init 属性,即让容器在解析注册 Bean 定义 时进行预实例化,触发依赖注入
BeanFactory 接口定义了 Spring IOC 容器的基本功能规范,是 Spring IOC 容器所应遵守的最底层和 最基本的编程规范。BeanFactory 接口中定义了几个 getBean 方法,就是用户向 IOC 容器索取管理的 Bean 的方法。
在 BeanFactory 中我们看到 getBean(String…)函数,它的具体实现在 AbstractBeanFactory 中。
2、AbstractBeanFactory 通过 getBean 向 IOC 容器获取被管理的 Bean,
在 Spring 中,如果 Bean 定义的单例模式 (Singleton),则容器在创建之前先从缓存中查找,以确保整个容器中只存在一个实例对象。如果 Bean定义的是原型模式(Prototype),则容器每次都会创建一个新的实例对象。除此之外,Bean 定义还可 以扩展为指定其生命周期范围。
3、具体的依赖注入实现在以下两个方法中:
(1).createBeanInstance:生成 Bean 所包含的 java 对象实例。
(2).populateBean :对 Bean 属性的依赖注入进行处理
详细可以从我的GitHub下载源码进行学习,对关键步骤我都有进行注释。如果对您有帮助,麻烦三连,您的支持,是我进行原创最大的动力!
额外信息补充:
定位:资源配置和定位,包括import、classpath、url;
加载:解析配置文件,把bean包装为beanDefinition对象,BeanDefinition 相当于是保存在内存中的配置文件,保存了所有的跟类属性相关信息;
注册:把已经初始化的BeanDefinition对象放入到IOC容器中;
依赖注入DI,就是把BeanDefinition中的信息读取出来,利用反射机制,或者代理机制创建对象,新创建的对象,不会放到我们印象中的IOC容器中,它存入到另外一个cache容器;
减少代码侵入,能够在原生的基础之上,再进行扩展,监听器、回调函数、标记信息;
原生 Bean: 通过反射或者代理机制创建的Bean;
BeanWrapper: 是原生Bean的包装,通过构造方法实现包装,真正操作的是Wrapper,放入cache的只是Wrapper;
FacoryBean:是Spring中最顶层接口,只要是通过工厂创建Bean,都要实现FacotryBean;
parseBeanDefinitions 方法实际是解析xml,把xml中的内容变成BeanDefinition;
补充一些IOC一些其他高级特性
1、如使用 lazy-init 属性对 Bean 预初始化;
2、FactoryBean 产生或 者修饰 Bean 对象的生成;
3、IOC 容器初始化 Bean 过程中使用 BeanPostProcessor 后置处理器对 Bean 声明周期事件管理;
4、IOC 容器的 autowiring 自动装配功能等;
1、Spring IOC 容器的 lazy-init 属性实现预实例化:
通过前面我们对 IOC 容器的实现和工作原理分析,我们知道 IOC 容器的初始化过程就是对 Bean 定 义资源的定位、载入和注册,此时容器对 Bean 的依赖注入并没有发生,依赖注入主要是在应用程序第 一次向容器索取 Bean 时,通过 getBean 方法的调用完成。 当Bean定义资源的元素中配置了lazy-init属性时,容器将会在初始化的时候对所配置的Bean 进行预实例化,Bean 的依赖注入在容器初始化的时候就已经完成。
2、FactoryBean和BeanFactory的区别
BeanFactory主语是factory,具体工厂会通过策略模式去实现,不同的工厂生成不同的产品;
FacoryBean:是Spring中最顶层接口,只要是通过工厂创建Bean,都要实现FacotryBean;
BeanFactory生产的产品都是FacoryBean
大部分情况下,BeanFactory本身也是由BeanFactory创建的,也就是说BeanFactory也是FactoryBean
spring中所有的bean都是FactoryBean。
3、BeanPostProcessor 后置处理器的实现:
BeanPostProcessor 后置处理器是 Spring IOC 容器经常使用到的一个特性,这个 Bean 后置处理器是 一个监听器,可以监听容器触发的 Bean 声明周期事件。后置处理器向容器注册以后,容器中管理的 Bean 就具备了接收 IOC 容器事件回调的能力。
4、Spring IOC 容器 autowiring 实现原理:
Spring IOC 容器提供了两种管理 Bean 依赖关系的方式:
a.显式管理:通过 BeanDefinition 的属性值和构造方法实现 Bean 依赖关系管理。
b.autowiring:Spring IOC 容器的依赖自动装配功能,不需要对 Bean 属性的依赖关系做显式的声明, 只需要在配置好 autowiring 属性,IOC 容器会自动使用反射查找属性的类型和名称,然后基于属性的 类型或者名称来自动匹配容器中管理的 Bean,从而自动地完成依赖注入。
通过对 autowiring 自动装配特性的理解,我们知道容器对 Bean 的自动装配发生在容器对 Bean 依赖 注入的过程中。在前面对 Spring IOC 容器的依赖注入过程源码分析中,我们已经知道了容器对 Bean 实例对象的属性注入的处理发生在 AbstractAutoWireCapableBeanFactory 类中的 populateBean 方法中。
autowiring 的实现过程:
a.对 Bean 的属性代调用 getBean 方法,完成依赖 Bean 的初始化和依赖注入。
b.将依赖 Bean 的属性引用设置到被依赖的 Bean 属性上。
c.将依赖 Bean 的名称和被依赖 Bean 的名称存储在 IOC 容器的集合中。
Spring IOC 容器的 autowiring 属性自动依赖注入是一个很方便的特性,可以简化开发时的配置,但 是凡是都有两面性,自动属性依赖注入也有不足,首先,Bean 的依赖关系在配置文件中无法很清楚地 看出来,对于维护造成一定困难。其次,由于自动依赖注入是 **Spring 容器自动执行的,容器是不会智 能判断的,**如果配置不当,将会带来无法预料的后果,所以自动依赖注入特性在使用时还是综合考虑。