spring到底什么时候进行bean实例化

这个问题看似简单实则坑多。

  • 1、很早以前有人告诉我说,spring是在你使用该bean的时候,通过动态代理给你实例化出来的。
  • 2、后来又有人告诉我说,spring是在容器启动的时候就将bean都给你实例化好了。

那么究竟哪个正确呢?其实这么回答都不正确,spring对bean的初始化其实是有条件的。
首先判断是单例还是多例,如果是多例的情况下,肯定是在你第一次使用该bean的时候初始化无疑。
但是如果是单例的情况下又分为两种情况:

  • 一是当你lazy-init懒加载设置为true时是在你第一次使用的时候实例化;第一次使用包括的范围是此对象被其它bean引用也算第一次使用,所以即使你设置lazy-initture只要你的此bean被引用或者注入也会被初始化。
  • 二是lazy-init懒加载为false时(这也是spring默认值)是在spring容器启动时进行实例化。

以下我们来看下spring实例化bean的源码你就知道了
查看AbstractApplicationContext.refresh()方法中实例化所有非懒加载的bean过程即
这个方法finishBeanFactoryInitialization查看此方法最后一行beanFactory.preInstantiateSingletons();实际调用此方法我们来看此单例实例化过程
DefaultListBeanFactory.preInstantiateSingletons源码如下

public void preInstantiateSingletons() throws BeansException {
//此处省略无数行代码。。。。。
		for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			//此处做出了判断必须是非抽象的并且必须是单例的并且必须是非懒加载的。
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				//此处省略无数行代码
		}

	}
	//此处省略无数行代码
}

从以上代码的循环中的条件我们不难看出容器启动过程中会实例化的bean只有满足以下三个条件的bean

  • 非抽象的
  • 单例的
  • 非懒加载的
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章