今天详细学习了一遍SpringIOC加载过程,将网上搜集到的信息进行了下整理,期望能对您起到帮助。
本文大部分取自影公子的博客他写得十分详细。
加载容器
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:application.xml");
进行ClassPathXmlApplicationContext的refresh()方法
@Override
public void refresh() throws BeansException, IllegalStateException {
// 来个锁,不然 refresh() 还没结束,你又来个启动或销毁容器的操作,那不就乱套了嘛
synchronized (this.startupShutdownMonitor) {
// 准备工作,记录下容器的启动时间、标记“已启动”状态、处理配置文件中的占位符
prepareRefresh();
// 这步比较关键,这步完成后,配置文件就会解析成一个个 Bean 定义,注册到 BeanFactory 中,
// 当然,这里说的 Bean 还没有初始化,只是配置信息都提取出来了,
// 注册也只是将这些信息都保存到了注册中心(说到底核心是一个 beanName-> beanDefinition 的 map)
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,手动注册几个特殊的 bean
prepareBeanFactory(beanFactory);
try {
// 这里需要知道 BeanFactoryPostProcessor 这个知识点,Bean 如果实现了此接口,
// 那么在容器初始化以后,Spring 会负责调用里面的 postProcessBeanFactory 方法。
// 这里是提供给子类的扩展点,到这里的时候,所有的 Bean 都加载、注册完成了,但是都还没有初始化
// 具体的子类可以在这步的时候添加一些特殊的 BeanFactoryPostProcessor 的实现类或做点什么事
postProcessBeanFactory(beanFactory);
// 调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 回调方法
invokeBeanFactoryPostProcessors(beanFactory);
// 注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别
// 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
// 两个方法分别在 Bean 初始化之前和初始化之后得到执行。这里仅仅是注册,之后会看到回调这两方法的时机
registerBeanPostProcessors(beanFactory);
// 初始化当前 ApplicationContext 的 MessageSource,国际化
initMessageSource();
// 初始化当前 ApplicationContext 的事件广播器
initApplicationEventMulticaster();
// 从方法名就可以知道,典型的模板方法(钩子方法)
// 具体的子类可以在这里初始化一些特殊的 Bean(在初始化singletonbeans之前)
onRefresh();
// 注册事件监听器,监听器需要实现 ApplicationListener 接口。
registerListeners();
// 重点,重点,重点
// 初始化所有的 singleton beans
//(lazy-init 的除外)
finishBeanFactoryInitialization(beanFactory);
// 最后,广播事件,ApplicationContext 初始化完成
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.
// 销毁已经初始化的 singleton 的 Beans,以免有些 bean 会一直占用资源
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// 把异常往外抛
throw ex;
}
finally {
resetCommonCaches();
}
}
}
(1)synchronized:为代码块加锁,防止并发占用
(2)prepareRefresh():做准备工作的,记录容器的启动时间、标记“已启动”状态、处理配置文件中的占位符
(3)ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory():配置文件解析成一个个Bean,并且注册到BeanFactory中,注意这里只是注册进去,并没有初始化。beanName-> beanDefinition 的 map
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
//返回刚刚创建的BeanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
① refreshBeanFactory():关闭旧的 BeanFactory (如果有),创建新的 BeanFactory,加载 Bean 定义、注册 Bean 等
@Override
protected final void refreshBeanFactory() throws BeansException {
//如果之前有BeanFactory,销毁所有bean,删除BeanFactory
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
//初始化功能最大的BeanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
//序列化
beanFactory.setSerializationId(getId());
//是否允许 Bean 覆盖、是否允许循环引用**
customizeBeanFactory(beanFactory);
//根据配置,加载各个 Bean,然后放到 BeanFactory
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
(4)实现了 BeanFactoryPostProcessor 接口的 Bean 都已经初始化并且其中的 postProcessBeanFactory(factory) 方法已经得到回调执行了。而且 Spring 已经“手动”注册了一些特殊的 Bean,如 ‘environment’、‘systemProperties’ 等。
(5)finishBeanFactoryInitialization(beanFactory):初始化所有的 singleton beans。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 注册这个bean之后,类似于前端传给后端的非基础类型和基础类型的包装类之外,其他的就可以考虑采用ConversionService来进行类型等的转换
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
//在此处初始化
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}
① beanFactory.preInstantiateSingletons()
this.beanDefinitionNames 保存了所有的 beanNames,然后再循环,判断非抽象、非懒加载的 singletons,如果是FactoryBeanFactoryBean 的话,在 beanName 前面加上 ‘&’ 符号,再调用getBean(beanName);,如果是普通的bean,那么直接getBean(beanName);,这里都是在循环中的,循环结束后,所有的非单例bean就初始化完成了
getBean()->createBean(beanName, mbd, args)->Object beanInstance = doCreateBean(beanName, mbdToUse, args)->createBeanInstance(beanName, mbd, args):实例化Bean
-
首先确保已经加载过这个class
-
然后检验一下权限
-
采用工厂方法实例化
-
工厂方法不行->构造函数依赖注入->无参构造函数:那说明不存在方法覆写,使用 java 反射进行实例化,如果不进入使用 CGLIB进行实例化
populateBean(beanName, mbd, instanceWrapper):属性注入
- 通过名字找到所有属性值,如果是 bean 依赖,先初始化依赖的 bean。记录依赖关系。
- 名字找不到则通过类型装配
- 对采用 @Autowired、@Value 注解的依赖进行设值
- 设置 bean 实例的属性值了到这里,属性注入就完成了
总结:
初始化容器
- Application加载xml
- AbstractApplicationContext的refresh函数载入Bean定义过程
创建BeanFactory
- AbstractApplicationContext子类的refreshBeanFactory()方法
注册BeanDefinitions至BeanFactory
- AbstractRefreshableApplicationContext子类的loadBeanDefinitions方法
- AbstractBeanDefinitionReader读取Bean定义资源
- 资源加载器获取要读入的资源
- XmlBeanDefinitionReader加载Bean定义资源
- DocumentLoader将Bean定义资源转换为Document对象
- XmlBeanDefinitionReader解析载入的Bean定义资源文件
- DefaultBeanDefinitionDocumentReader对Bean定义的Document对象解析
- BeanDefinitionParserDelegate解析Bean定义资源文件中的元素
- BeanDefinitionParserDelegate解析元素
- 解析元素的子元素
- 解析子元素
- 解析过后的BeanDefinition在IoC容器中的注册(IoC容器的初始化结束)
实例化Bean
- DefaultListableBeanFactory向IoC容器注册解析后的BeanDefinition(依赖注入开始)
- AbstractBeanFactory通过getBean向IoC容器获取被管理的Bean
- AbstractAutowireCapableBeanFactory创建Bean实例对象
- createBeanInstance方法创建Bean的java实例对象
- SimpleInstantiationStrategy类使用默认的无参构造方法创建Bean实例化对象
Bean属性注入
- populateBean方法对Bean属性的依赖注入
- BeanDefinitionValueResolver解析属性值
- BeanWrapperImpl对Bean属性的依赖注入