文章来源于微信公众号:三太子敖丙
IOC控制反转
类的创建、销毁都是由spring来控制,控制对象生存周期的不再是引用它的对象,而是由spring来控制整个过程。
1、通过BeanDefinitionReader加载bean的配置信息,生成一个BeanDefinition(bean的定义信息,用来存储bean的所有属性方法定义)。
2、BeanFactoryPostProcessor接口是Spring初始化BeanFactory时对外暴露的扩展点,在bean实例化之前,获取bean的定义信息及修改相关信息。
3、BeanFactory是生产bean的工厂,他负责生产和管理各个bean实例,也是Spring容器暴露在外获取bean的入口;BeanFactory的生产过程其实是利用反射机制实现的。
Bean的生命周期
1、BeanNameAware#setBeanName:在创建此bean工厂中设置bean的名称,在普通属性设置之后调用的,在InitializingBean.afterPropertiesSet()方法之前调用。
2、BeanClassLoaderAware#setBeanClassLoader:将bean ClassLoader提供给bean实例的调用。
3、BeanFactoryAware#setBeanFactory:回调提供了自己的bean实例工厂,在普通属性设置之后,在InitializingBean.afterPropertiesSet()或者自定义初始化方法之前调用。
4、org.springframework.context.ResourceLoaderAware#setResourceLoader:在普通bean对象之后调用,在afterPropertiesSet 或者自定义的init-method 之前调用,在 ApplicationContextAware 之前调用。
5、org.springframework.context.ApplicationEventPublisherAware#setApplicationEventPublisher:在普通bean属性之后调用,在初始化调用afterPropertiesSet 或者自定义初始化方法之前调用。在 ApplicationContextAware 之前调用。
6、org.springframework.context.MessageSourceAware#setMessageSource:在普通bean属性之后调用,在初始化调用afterPropertiesSet 或者自定义初始化方法之前调用,在 ApplicationContextAware 之前调用。
7、org.springframework.context.ApplicationContextAware#setApplicationContext:在普通Bean对象生成之后调用,在InitializingBean.afterPropertiesSet之前调用或者用户自定义初始化方法之前。在ResourceLoaderAware.setResourceLoader,ApplicationEventPublisherAware.setApplicationEventPublisher,MessageSourceAware之后调用。
8、org.springframework.web.context.ServletContextAware#setServletContext:运行时设置ServletContext,在普通bean初始化后调用。
9、org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization:将此BeanPostProcessor 应用于给定的新bean实例。
10、InitializingBean#afterPropertiesSet:在设置所有 bean 属性后由包含的 BeanFactory调用。
11、org.springframework.beans.factory.support.RootBeanDefinition#getInitMethodName:获取InitMethodName名称,并且运行初始化方法。
12、org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization。
13、DisposableBean#destroy:销毁。
14、org.springframework.beans.factory.support.RootBeanDefinition#getDestroyMethodName:返回被销毁的bean名称。
public void refresh() throws BeansException, IllegalStateException{
// 添加一个synchronized 防止出现refresh还没有完成出现其他的操作(启动,或者销毁)
synchronized (this.startupShutdownMonitor) {
// 1.准备工作
// 记录下容器的启动时间、
// 标记“已启动”状态,关闭状态为false、
// 加载当前系统属性到环境对象中
// 准备一系列监听器以及事件集合对象
prepareRefresh();
// 2. 创建容器对象:DefaultListableBeanFactory,加载XML配置文件的属性到当前的工厂中(默认用命名空间来解析),就是上面说的BeanDefinition(bean的定义信息)这里还没有初始化,只是配置信息都提取出来了,(包含里面的value值其实都只是占位符)
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 3. BeanFactory的准备工作,设置BeanFactory的类加载器,添加几个BeanPostProcessor,手动注册几个特殊的bean等
prepareBeanFactory(beanFactory);
try {
// 4.子类的覆盖方法做额外的处理,就是我们刚开始说的 BeanFactoryPostProcessor ,具体的子类可以在这步的时候添加一些特殊的BeanFactoryPostProcessor完成对beanFactory修改或者扩展。
// 到这里的时候,所有的Bean都加载、注册完成了,但是都还没有初始化
postProcessBeanFactory(beanFactory);
// 5.调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 方法
invokeBeanFactoryPostProcessors(beanFactory);
// 6.注册 BeanPostProcessor 处理器 这里只是注册功能,真正的调用的是getBean方法
registerBeanPostProcessors(beanFactory);
// 7.初始化当前 ApplicationContext 的 MessageSource,即国际化处理
initMessageSource();
// 8.初始化当前 ApplicationContext 的事件广播器,
initApplicationEventMulticaster();
// 9.从方法名就可以知道,典型的模板方法(钩子方法),感兴趣的同学还可以再去复习一下之前写的设计模式中的-模版方法模式
// 具体的子类可以在这里初始化一些特殊的Bean(在初始化 singleton beans 之前)
onRefresh();
// 10.注册事件监听器,监听器需要实现 ApplicationListener 接口。这也不是我们的重点,过
registerListeners();
// 11.初始化所有的 singleton beans(lazy-init 的除外),重点关注
finishBeanFactoryInitialization(beanFactory);
// 12.广播事件,ApplicationContext 初始化完成
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 13.销毁已经初始化的 singleton 的 Beans,以免有些 bean 会一直占用资源
destroyBeans();
cancelRefresh(ex);
// 把异常往外抛
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
常见面试题:
1、BeanFactory和ApplicationContext的区别?
BeanFactory:是一个底层的IOC容器;
ApplicationContext:在BeanFactory的基础上增加了一些他的特性的同时,又增加了一些其他的整合特性,比如:更好的整合了SpringAOP、国际化消息、事物的发布、资源访问等等。
2、BeanFactory 与 FactoryBean的区别?
BeanFactory:是IOC底层容器。
FactoryBean:是创建bean的一种方式,帮助实现复杂的初始化逻辑。
3、Spring IoC 容器的启动过程?(见ApplicationContext.refresh()方法中的内部13个子方法)。