Spring的IOC容器的核心实现原理是什么
(一共13个方法,看一下Spring IoC 源码,类、方法、注解)
1.准备工作
在Spring 开始启动的时候,它会跳到一个refresh方法里面去,refresh包含了13个核心方法,这些方法最开始的时候,会提供一些刷新前的准备工作,比如说会创建某些集合对象,设置某些基本的特征类,
然后会去创建好容器对象,然后会把我们需要创建对象的一些定义信息加载到容器中,用XML或者注解的方式,XML或者注解会通过他们独特的解析方式把它转换成对应的BeanDefinition(一个接口),
然后会放到一个Map容器中,叫BeanDefinitionMap,当拿到完整的BeanDefinitionMap之后,就可以进行后续的实例化过程了
注1:准备工作中有个重要的组件叫监听器,这里用到了观察者模式,里面有广播器Multicaster、有监听器Listener、还有发布事件Event
注2:Spring也会提供容器的扩展性,所以在BeanDefinition创建完成之后,会对Beanfactory中的一些信息做出某些修改工作(比如数据源配置,用占位符方式;那么在BeanfactoryPostProcess实现里面进行扩展实现,把这些占位符替换成我们需要的实际的值)
2.以上准备工作做完之后:
1)会通过反射的方式从BeanDefinition中拿到对应的信息,然后进行实例化;
2)实例化完成之后,会进行相关的属性设置工作,包括某些Bean对象的扩展工作,以及我的使用过程
3)当我用完了,这个对象已经不需要的时候,我会关闭我的容器,关闭容器的时候会触发销毁过程,同时会触发某些事件告诉Spring以什么方式来结束销毁,包括清空对应的缓存信息
容器中bean的实例化:当所有beanDefinition对象都已经准备好之后,spring框架会在容器初始化时就调用getBean—> doGetBean—> createBean—> doCreateBean这个流程将所有的bean对象进行初始化过程,所有的bean对象最后存储的容器是DefaultListableBeanFactory;
beanPostProcessor(bean的实例化阶段):bean对象的后置处理,在bean真正初始化之前,我们可以通过实现这个接口对bean的有关属性,或者方法进行修改,在spring中有AOP就是通过beanPostProcessor在bean创建之后创建bean的代理对象;
对于spring容器启动到bean初始化整个过程,spring都统一将这个过程放到了AbstractApplicationContext.refresh()这个方法中,读懂这个方法的核心步骤,也就理解了spring容器是如何启动并加载bean对象的;源码如下
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. /** * 做容器刷新前的准备工作 * 1、设置容器的启动时间 * 2、设置活跃状态为true * 3、设置关闭状态为false * 4、获取Environment对象,并加载当前系统的属性值到Environment对象中 * 5、准备监听器和事件的集合对象,默认为空的集合 */ prepareRefresh(); // Tell the subclass to refresh the internal bean factory. // 创建容器对象:DefaultListableBeanFactory // 加载xml配置文件的属性值到当前工厂中,最重要的就是BeanDefinition ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. // beanFactory的准备工作,对各种属性进行填充 prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. // 子类覆盖方法做额外的处理,此处我们自己一般不做任何扩展工作,但是可以查看web中的代码,是有具体实现的 postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. // 调用各种beanFactorypostProcessor进行beanDefinition的增强处理 invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. // 注册beanPostprocessor,这里只是注册功能,真正调用的是getBean方法(核心四步:getBean——>doGetBean——>createBean——>doCreateBean) registerBeanPostProcessors(beanFactory); // Initialize message source for this context. // 为上下文初始化message源,即不同语言的消息体,国际化处理,在springmvc的时候通过国际化的代码重点讲 initMessageSource(); // Initialize event multicaster for this context. // 初始化事件监听多路广播器 initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. // 留给子类来初始化其他的bean onRefresh(); // Check for listener beans and register them. // 在所有注册的bean中查找listener bean,注册到消息广播器中 registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. // 初始化剩下的单实例(非懒加载的) finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. // 完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人 finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. // 为防止bean资源占用,在异常处理中,销毁已经在前面过程中生成的单件bean destroyBeans(); // Reset 'active' flag. // 重置active标志 cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } }
总结:
1.控制反转:原来的对象是由使用者来进行控制,有了Spring之后,可以把整个对象交给Spring来帮我们进行管理
2.容器:存储对象,使用map结构来存储,在Spring中一般存在三级缓存,singletonObject存放完整的bean对象,整个bean的生命周期,从创建到使用再到销毁的过程全部都是由容器来管理
3.DI:依赖注入,把对应的属性的值注入到具体的对象中,比如@Autowired、@Resource完成属性的注入

大致流程为:
1.IOC容器从xml,注解等地方获取类的信息。
2.将类的信息封装成BeanDefinition
3.beanFactoryPostProcessor前置处理
4.ioc容器获取类信息通过反射进行实例化
5.执行实例化
6.执行初始化逻辑(填充属性(populateBean)->执行aware接口方法->beanPostProcessor:before->init-method->beanPostProcessor:after)
 
                    
                     
                    
                 
                    
                 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号