Spring源码解析(一):IOC和容器初始化
Spring是现在很火的一个框架,从早几年的ssh到ssm,又到现在的springBoot、springCloud,都有spring的身影,可以说学习Java,一定是和spring离不开的。
而谈到spring,往往就是IOC和AOP了。而估计很多人虽然使用了很久的spring但也只是“使用”,现在我和大家一起来揭开这层“面纱”。
首先,我们来了解spring IOC,官方文档描述“控制反转(IOC)”也称为“依赖注入(DI)”,并且解释一个定义对象依赖的过程,对象只和构造参数,工程方法
参数,对象实例属性或则工厂方法返回相关。容器在创建这些bean的时候注入这些依赖,这个过程是一个反向的过程...这些都是官方介绍,避免有点“官方”,通俗点
spring其实可以看成一个容器,我们把要使用的对象交由给spring管理,要使用时在通过依赖注入(DI)进行注入,这可能和我们平时要用到对象时就new不一样,
它是一个反向的过程,也之所以就叫IOC。这样子有什么好处,我认为最大的好处就是“解耦”。
前面说到spring是一个“容器式”框架,那么就存在一个容器的初始化的问题,平时我们在使用spring初始化容器时,最常见的无非就是三种:
一:通过new ClasspathXmlApplicationContext();
二:ContextLoaderListener
三:DispatcherServlet
平时开发中使用的最多的应该就是后面两种了。
首先我们得知道,在spring中,构建容器的过程中都是同步(synchronuzed)的,同步操作是为了保证容器构建的过程,不出现多线程资源冲突问题,也就是“锁”的问题。
而ApplicationContext容器的初始化流程主要由AbstractApplicationContext类中的refresh方法实现
prepareRefresh() 容器预加载。
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); BeanFactory的创建。BeanFactory是ApplicationContext父接口,是spring的顶级
容器工厂对象。由于BeanFactory只能管理bean对象。没有其他功能, 所以随着spring框架的发展如aop 切面管理, propertyplaceholder 的加载等。所以现在
基本使用ApplicationContext,BeanFactory也随之淡忘,当然在资源匮乏的环境可以使用BeanFactory.但是现在基本不会有这种可能。作用:构建BeanFactory
的功能就是管理bean对象。
prepareBeanFactory(beanFactory); 创建BeanFactory管理的bean对象,这里也就体现了ApplicationContext和BeanFactory的区别,ApplicationContext创建完bean
对象也就创建完了,而BeanFactory不会。
postProcessBeanFactory(beanFactory); 加载配置中BeanFactory无法处理的内容,如propertyplaceholder 的加载
invokeBeanFactoryPostProcessors(beanFactory); 将上一步加载的内容,作为一个容器可以管理的bean对象注册到ApplicationContext中,底层实质是在将
postProcessBeanFactory中加载的内容包装成一个容器ApplicationContext可以管理的bean对象 。
registerBeanPostProcessors(beanFactory); 继续完成注册操作,配置文件中配置的bean对象都创建并注册完成。
iinitMessageSource(); i18n,国际化。初始化国际化消息源。做过跨国的话应该了解,比如一个网站,中国访问就是中文,美国访问就是英文。其本质是根据客户端发起
请求时带的语种信息,到服务器的MessageSource中去找对应的。
initApplicationEventMulticaster(); 注册事件多播监听。如 ApplicationEvent 事件。是 spring 框架中的观察者模式实现机制。
onRefresh(); 初始化主题资源(ThemeSource)。spring 框架提供的视图主题信息。 应用比较少,因为spring做视图逻辑不是很适合。
registerListeners(); registerListeners- 创建监听器,并注册。
finishBeanFactoryInitialization(beanFactory); 初始化配置中出现的所有的lazy-init=false的bean对象。 且 bean 对象必须是 singleton 的。
finishRefresh(); 最后一步。 发布最终事件。生命周期监听事件。 spring 容器定义了生 命周期接口。可以实现容器启动调用初始化,容器销毁之前调用回收资源。Lifecycle 接口。
本人也处于学习阶段,以上如有错误或不恰当之处,欢迎指正....