IOC和DI说明 IOC(Inversion of Control)控制反转:所谓控制反转,就是把原先我们代码里面需要实现的对象创 建、依赖的代码,反转给容器来帮忙实现。那么必然的我们需要创建一个容器,同时需要一种描述来让 容器知道需要创建的对象与对象的关系。这个描述最具体表现就是我们可配置的文件。 DI(Dependency Injection)依赖注入:就是指对象是被动接受依赖类而不是自己主动去找,换句话说 就是指对象不是从容器中查找它依赖的类,而是在容器实例化对象的时候主动将它依赖的类注入给它。 可能有很多官方的解释,但我所理解的IOC容器,其实就可以理解成spring维护的一个Map<String,Object>。各个对象之间的关系以及所有的bean的信息,都由spring Ioc容器来储存,实例的生命周期由IOC容器控制。当然,若想要spring帮你管理,那你就必须按照spring的规则来,其中比较常用的两种方式是xml和注解方式。 Spring 架构图 本文主要讲述的是最下边的Core container模块,也是spring的核心模块 Spring 核心容器体系结构
DefaultListableBeanFactory中有一个成员变量 private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap(256);在注册阶段变化给其赋值,将xml或者其他的配置转换为spring能理解的数据结构从而可以在getbean阶段可以得到实例。
主线说明 Spring在IOC和DI的过程主要分为两步: 1. IOC容器初始化 2. 依赖注入getbean IOC初始化步骤
注册
<bean id='helloWorld' class='org.czx.spring.ioc.HelloWorld'> <property name='name' value='Spring'></property></bean> 使用xml的ClassPathXmlApplicationContext的refresh()方法,初始化,加载资源 xml解析,转换为docment对象,然后解析docment对象,对于不同element节点进行做不同的处理,最后转换成BeanDefinition的定义格式,根据id等其他唯一标识,将bean的定义存入缓存中,完成IOC容器的初始化。这个是主线,对于校验,多种格式的解析,是否单例处理,这些就需要看具体处理逻辑了。至此就完成了初始化阶段,所以可以看出来初始化阶段容器并不会去生成对象,除非bean配置lazy-init=ture; 依赖注入getbean 当我们调用getbean方法时候就会触发依赖注入了,将属性值或者属性对象都会根据配置去生成,spring生成的对象怎样一切依赖的配置,spring并不干涉。 依赖注入流程: 依赖注入过程就是生成一个对象,将属性和配置的value值进行对应,然后使用工厂去生成,在这里大量使用策略模式,对于不同对象需要不同的模型去产生。还有一个金典的地方需要注意的是产生的并不是一个我们定义的对象,spring巧妙的运用了装饰器模式定义一个BeanWrapper,最后产生的bean都是beanWrapper,这个beanwrapper是bean的一个增强,在docreatebean时候,可以通过反射去生成一个beanWrapper也可以通过动态代理去实现beanWrapper,这也就是为之后spring实现AOP的功能做了铺垫。 结语 对于Spring ioc的很多细节没有说明,源码需要自己去看才知道细节的实现,对于spring的ioc和di的具体实现,可以看看github上简要的实现: |
|