spring笔记⑮——bean初始化(实例化)详解

本文详细解析了Spring框架中bean的初始化过程,重点介绍了FactoryMethod的概念和作用,以及bean从预初始化到通过反射实例化的调用链。文章涵盖了`preInstantiateSingletons`、`doGetBean`、`getSingleton`、`createBean`等关键方法的职责,揭示了Spring如何根据配置选择构造器并实例化bean。
摘要由CSDN通过智能技术生成

springIOC容器宏观上是spring的整个环境,微观上来看就是一个map,存放着bean的名字和对应的bean对象

FactoryMethod

FactoryMethod顾名思义就是工厂方法的意思,如果配置了工厂方法,那么spring就会通过这个工厂方法去实例化bean。

在xml配置文件中可以配置FactoryMethod,如果配置了FactoryMethod,在初始化bean对象的时候会直接调用FactoryMethod方法来实例化bean
在这里插入图片描述

public class RealDao {
   
	public void test(){
   
		System.out.println("RealDao");
	}
}

注意工厂方法必须是static方法

public class TestDao {
   

	public void test(){
   
		System.out.println("TestDao");
	}


	// 工厂方法必须是static方法
	// spring会直接调用这个方法来初始化bean
	public static RealDao initFactoryMethod(){
   
		return new RealDao();
	}

}
public static void main(String[] args) {
   
	AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);

	//可以看到拿到的是工厂方法返回的bean对象
	RealDao testDao = (RealDao) annotationConfigApplicationContext.getBean("testDao");

	testDao.test();
	// RealDao
}

输出

RealDao

在spring源码中是在下面的位置判断bean是否配置了工厂方法并调用工厂方法
在这里插入图片描述
调用链如下
在这里插入图片描述

在配置类中@Bean注解的方法如果是static修饰的,那么这种bean的实例化就是通过FactoryMethod实现的。

bean的初始化

bean的实例化过程是在refresh中执行的,具体来说是在finishBeanFactoryInitialization这个方法中执行的
在这里插入图片描述

调用链

直到一个普通的bean被反射实例化(使用的默认构造器)的调用链如下
在这里插入图片描述
这里我会分析一些比较重要的方法其中干了什么,其中一些只是单纯的包装调用其他方法的方法就不会分析了。

preInstantiateSingletons

这个方法在初始化bean之前对bean做了一些初始化之前的准备
在这里插入图片描述
源码如下,这里是getBean方法去执行真正的bean实例化,在此之前会判断bean是否是抽象类、非单例、懒加载,如果是的话就会直接跳过实例bean,之后还要判断是不是factorybean,同样如果是的话也不会通过上面的调用链实例化bean。

@Override
public void preInstantiateSingletons() throws BeansException {
   
	if (logger.isDebugEnabled()) {
   
		logger.debug("Pre-instantiating singletons in " + this);
	}

	// Iterate over a copy to allow for init methods which in turn register new bean definitions.
	// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
	// 得到所有的beanName
	List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

	// Trigger initialization of all non-lazy singleton beans...
	for (String beanName : beanNames) {
   
		RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
		//判断是否是抽象类、单例、懒加载
		//只有非抽象类、单例、非懒加载的类才会进入if去实例化bean
		if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
   
			//判断是不是factorybean
			if (isFactoryBean(beanName)) {
   
				Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
				if (bean instanceof FactoryBean) {
   
					final FactoryBean<?> factory = (FactoryBean<?>) bean;
					boolean isEagerInit;
					if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
   
						isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
										((SmartFactoryBean<?>) factory)::isEagerInit,
								getAccessControlContext());
					}
					else {
   
						isEagerInit = (factory instanceof SmartFactoryBean &&
								((SmartFactoryBean<?>) factory).isEagerInit());
					}
					if (isEagerInit) {
   
						getBean(beanName);
					}
				}
			}
			else {
   
				// 真正非factorybean的bean的实例化方法
				getBean(beanName);
			}
		}
	}

	// Trigger post-initialization callback for all applicable beans...
	for (String beanName : beanNames) {
   
		Object singletonInstance = getSingleton(beanName);
		if (singletonInstance instanceof SmartInitializingSingleton) {
   
			final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
			
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值