Spring IOC容器启动示例分析
每天都要进步一点点 人气:0一、简介
Spring核心有两个:
- IOC:控制反转
- AOP:面向切面编程
相信大家在项目中都使用过Spring进行开发,都知道Spring非常强大,那么在熟练掌握Spring进行开发后,我们有必要去了解一下其中的原理,Spring工作原理也是面试中必问的一个环节,先来看看几道常见的面试题,想想看,如果被面试官问到,你会怎么答?
- Spring IOC的工作原理?
- Spring Bean的生命周期是怎样的?
- Spring 中使用到了哪些设计模式?
- Spring是如何解决循环依赖的?
- BeanFactory和FactoryBean的区别是什么?
- ....
显然,我们需要从源码中获取我们想要的答案,本篇文章我们先来分析一下Spring中IOC容器整个初始化过程,本篇文章暂且先不详细分析源码实现,先把整个流程理清,后面再针对其中一些重要的环节逐个分析源码是如何实现的,这样可能没那么懵,不然一进来就直接一个一个细节去抠,可能跟着跟着不知道从哪个方法进来的了。
二、IOC整体流程
Spring IOC的核心工厂类其实就是BeanFactory,从名字上也很好理解,生产 bean 的工厂,它负责生产和管理各个 bean 实例。在项目中我们更多的是使用它的子类或者实现类,像常见的AbstractApplicationContext、ApplicationContext、DefaultListableBeanFactory、ClassPathXmlApplicationContext、AnnotationConfigApplicationContext等等。
我们先来回顾一下最基本的启动 Spring 容器的例子:
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring-config.xml"); System.out.println(applicationContext.getBean("student"));
如上代码就可以利用XML配置文件来启动一个 Spring 容器。
public ClassPathXmlApplicationContext( String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException { super(parent); // 1、设置配置文件的路径 setConfigLocations(configLocations); if (refresh) { //2、容器刷新方法:IOC核心方法就是refresh() refresh(); } }
在ClassPathXmlApplicationContext的构造方法中,我们可以看到有一个refresh()方法,它是整个IOC容器的核心。
refresh()主要做了下述12件事情,先说个大概:
1、prepareRefresh()
容器刷新前的一些预处理工作。
2、obtainFreshBeanFactory()
创建DefaultListableBeanFactory工厂,给bean工厂设置一些属性,加载配置文件信息,封装成bean定义信息。
3、prepareBeanFactory(beanFactory)
同样,设置bean工厂的一些属性,如添加一些BeanPostProcessor增强器等。
4、postProcessBeanFactory(beanFactory)
模板方法,留给子类扩展实现。
5、invokeBeanFactoryPostProcessors(beanFactory)
执行BeanFactoryPostProcessor的postProcessBeanFactory ()增强方法。
6、registerBeanPostProcessors(beanFactory)
注册BeanPostProcessor增强器,注意这里只是注册,真正是在初始化阶段的前后执行。
7、initMessageSource()
初始化MessageSource,国际化处理。
8、initApplicationEventMulticaster()
初始化事件多播器。
9、onRefresh()
模板方法,留给子类扩展实现。
10、registerListeners()
注册一些监听器。
11、finishBeanFactoryInitialization(beanFactory)
IOC容器创建最重要的一个步骤:完成非懒加载的单例bean对象的实例化,包括反射创建bean对象、属性填充、循环依赖的处理、bean的初始化等等。
12、finishRefresh()
容器刷新完成之后的一些处理工作。
前面我们通过文字描述了refresh()方法主要的处理流程,下面通过两张图来说明,会更加形象,好理解一点:
这里可能稍微就涉及到一些细节了,有些许复杂,大家可以先过几遍,有个印象后自己再去看源码,相信会更加清晰里面的处理逻辑。
加载全部内容