IOC的启动流程(三)-Bean的生命周期&Bean的后置处理器&Bean的实例化

一、概述

这篇文章是接上一篇文章《IOC的启动流程(二)-解析配置与注册BeanDefinition》,上一章节我们见到了Spring IOC容器的解析配置注册BeanDefinition两个大的流程,接来下分析Bean的实例化以及Bean的属性注入流程。这里我在进行对IOC的启动流程再做次简要的概述。

IOC的启动流程依次主要做了这么几件事:

  1. 创建容器:加载配置文件,创建文件转换器,保存配置文件的地址,然后进行刷新容器。
  2. 加载配置:将配置文件的经过各种解析器进行加载,从Resource对象->Document对象
  3. 解析配置:解析Document对象中的imposrt、alias、bean,如果是bean类型会封装成BeanDefinition对象。
  4. 注册Bean:就将BeanDefinition对象注册到beanDefinitionMap 中。
  5. 实例化:获取BeanDefinition对象,然后实例化真正的Bean对象.
  6. 属性注入:为当前Bean的依赖Bean进行注入值。
  7. 初始化:先进行前置处理,调用Bean的默认初始化方法,后置处理。
  8. 注册IOC容器:对返回回来的Bean进行注册到IOC容器中。
    实例化开始,就是bean的生命周期的范畴了,写到这,就不得不提一下Bean的生命周期了,来接着往下看。

1、Bean的生命周期

具体的生命周期过程:

  1. bean对象创建(调用无参构造器)
  2. 给bean对象设置属性
  3. bean对象初始化之前操作(由bean的后置处理器负责,实现postProcessBeforeInitialization方法)
  4. bean对象初始化(需要配置bean时指定初始化方法)
  5. bean对象初始化之后操作(由bean的后置处理器负责,实现postProcessAfterInitialization方法)
  6. bean对象就绪可以使用
  7. bean对象销毁(需在配置bean是指定给你销毁方法)
  8. IOC容器关闭

总结起来就几步,可看到声明周期:

  1. 实例化
  2. 依赖注入
  3. 初始化,需要通过bean的init-method属性指定初始化方法
  4. 销毁,IOC容器关闭之前,需要通过bean的destroy-method属性指定销毁的方法

注意:

  • ConfigurableApplicationContext 是ApplicationContext的子接口,其中扩展了刷新和关闭容器的方法;
  • 若bean的作用域为单例时,生命周期的前三个步骤会在获取IOC容器时执行
  • 若bean的作用域为多例时,生命周期的前三个步骤会在获取bean时执行.

前面提到了后置处理器,我们看看什么是后置处理器?

二、Bean的后置处理器

Bean的后置处理器有多种,比如实例化后置处理器实现了InstantiationAwareBeanPostProcessor接口,初始化后置处理器实现了BeanPostProcessor接口,销毁后置处理器DestructionAwareBeanPostProcessor等等。‌

1、Bean的实例化后置处理器

通过实现InstantiationAwareBeanPostProcessor接口,可以在对象创建时注入依赖。例如,子类AutowiredAnnotationBeanPostProcessor用于处理@Autowired和@Value注解的依赖注入‌。

@Component
public class BeanInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
    @Nullable
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        System.out.println("实例化之前:" + beanName);
        return null;
    }
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        System.out.println("实例化之后:" + beanName);
        return true;
    }
    @Nullable
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
            throws BeansException {
        //System.out.println("属性填充之前:" + beanName);
        return null;
    }
    //在工厂将给定的属性值应用于给定的 bean 之前,对它们进行后处理。允许检查是否满足所有依赖项,例如基于 bean 属性 setter 上的“Required”注释。
    public PropertyValues postProcessPropertyValues(
            PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
        return pvs;
    }
}

输出结果:

实例化之前:fileSystemWatcherFactory
实例化之后:fileSystemWatcherFactory
在初始化之前执行,beanName:fileSystemWatcherFactory
在初始化之后执行,beanName:fileSystemWatcherFactory

2、Bean的初始化后置处理器

Bean的初始化后置处理器会在生命周期的初始化前后添加额外的操作,需要实现BeanPostProcessor接口且配置到IOC容器中,需要注意是,bean后置处理器不是单独针对某个bean生效,而是针对IOC容器中所有bean的初始化前后都会执行。

@Component
public class BeanPostHello implements BeanPostProcessor {
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("在初始化之前执行,beanName:" + beanName);
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("在初始化之后执行,beanName:" + beanName);
        return bean;
    }
}

输出结果:

在初始化之前执行,beanName:org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration
在初始化之后执行,beanName:org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration
在初始化之前执行,beanName:spring.lifecycle-org.springframework.boot.autoconfigure.context.LifecycleProperties
在初始化之后执行,beanName:spring.lifecycle-org.springframework.boot.autoconfigure.context.LifecycleProperties
在初始化之前执行,beanName:lifecycleProcessor
在初始化之后执行,beanName:lifecycleProcessor
......

3、Bean的销毁后置处理器

‌DestructionAwareBeanPostProcessor用于在Bean销毁之前进行自定义处理‌。

@Component
public class MyDestructionAwareBeanPostProcessor implements DestructionAwareBeanPostProcessor {
    @Override
    public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
        System.out.println(beanName + ":销毁之前执行");
    }
}

输出结果:


mappingJackson2XmlHttpMessageConverter销毁之前执行
jsonComponentModule销毁之前执行
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration销毁之前执行

三、回顾refresh()方法

在上一篇章中,把BeanDefinition对象注册到beanDefinitionMap 中,这意味着AbstractApplicationContext#refresh()方法的ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();方法执行完成。

	[class: AbstractApplicationContext]
	@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// 准备环境以便刷新。
			prepareRefresh();
			// 通知子类刷新内部bean工厂。
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
			// 准备一个Bean工厂,以便在此上下文中使用。
			prepareBeanFactory(beanFactory);
			try {
				// 允许在上下文子类中对bean工厂进行后处理。里面其实啥都没有。
				postProcessBeanFactory(beanFactory);
				// 调用BeanFactory的后置处理器BeanFactoryPostProcessor,在 bean定义注册之后bean实例化之前调用.
				invokeBeanFactoryPostProcessors(beanFactory);
				// 注册Bean的后置处理器BeanPostProcessor,在Bean初始化前,后执行
				registerBeanPostProcessors(beanFactory);
				// 初始化信息源,国际化相关操作。
				initMessageSource();
				// 初始化此上下文事件广播器。
				initApplicationEventMulticaster();
				// 空方法,该方法留给子类实现,在容器刷新的时候可以自定义逻辑;如创建Tomcat,Jetty等WEB服务器
				onRefresh();
				// 注册监听器
				registerListeners();
				// 实例化所有剩余的非延迟初始化的单例对象。
				finishBeanFactoryInitialization(beanFactory);
				// 最后一步,发布相应的事件。
				finishRefresh();
			}
			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}
				// 销毁已经创建的单例对象以避免悬挂资源。
				destroyBeans();
				// 取消容器刷新
				cancelRefresh(ex);
				// 将异常传递给调用者。
				throw ex;
			}

			finally {
				//在Spring框架的核心部分重置常见的反射缓存,因为对于单例Bean,我们可能再也不需要元数据了……
				resetCommonCaches();
			}
		}
	}

refresh() 方法主要就是准备容器上下文、创建容器、刷新容器、注册事件广播器、注册监听器、实例化相应对象等一系列操作。

容器创建配置加载配置解析BeanDefinition的注册主要通过obtainFreshBeanFactory方法来实现对IOC容器的刷新,同时这里面包含了绝大部分的对BeanDefinition注册相关操作。

然后Bean的实例化属性注入初始化Bean注册到IOC容器主要通过finishBeanFactoryInitialization(beanFactory);方法完成,这里面也包含了Bean的生命周期的全部流程。

我们从finishBeanFactoryInitialization(beanFactory);方法点进去,看看spring是如何完成Bean的一整个生命周期的。

四、Bean的实例化

1、AbstractApplicationContext#finishBeanFactoryInitialization()

	/**
	 * 完成此上下文中的bean工厂的初始化,
	 * 初始化所有剩余的singleton bean。
	 */
	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// 初始化此上下文的转换服务。
		//检查容器中是否存在名为 CONVERSION_SERVICE_BEAN_NAME 的Bean(默认为 "conversionService")
		//如果存在且类型为 ConversionService,则将其设置为Bean工厂的转换服务。
		//转换服务用于支持类型转换,例如在注解属性值解析时。
		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));
		}

		// 如果没有注册任何bean后置处理器(例如PropertyPlaceholderConfigurer bean),则注册一个默认的嵌入式值解析器:此时,主要用于注解属性值的解析。
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// 获取所有实现了 LoadTimeWeaverAware 接口的Bean名称。遍历这些Bean并提前实例化它们。这些Bean通常用于类加载增强(如字节码织入),提前初始化这些Bean可以确保它们的增强逻辑在其他Bean初始化之前生效。
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		// 停止使用Bean工厂的临时 ClassLoader。
		// 临时 ClassLoader 通常用于类型匹配阶段,避免类加载冲突。
		beanFactory.setTempClassLoader(null);

		// 允许缓存所有bean定义元数据,不期望进一步更改。
		// 冻结Bean工厂的配置,表示不再期望对Bean定义进行修改。
		beanFactory.freezeConfiguration();

		// 实例化所有剩余的(非懒加载)单例。
		// 这一步确保所有非懒加载的单例Bean在容器启动时被提前创建。
		beanFactory.preInstantiateSingletons();
	}

完成Bean工厂的初始化,包括设置转换服务、注册值解析器等。提前初始化某些特殊类型的Bean(如 LoadTimeWeaverAware)。实例化所有剩余的非懒加载单例Bean。
preInstantiateSingletons();方法的具体应用,是留给DefaultListableBeanFactory子类的实现。

2、DefaultListableBeanFactory#preInstantiateSingletons()

@Override
	public void preInstantiateSingletons() throws BeansException {
		//日志记录
		if (logger.isTraceEnabled()) {
			logger.trace("Pre-instantiating singletons in " + this);
		}
		//迭代一个副本,以允许init方法反过来注册新的bean定义。虽然这可能不是常规工厂引导的一部分,但它在其他方面工作得很好。

		//获取所有的bean的定义列表,为了避免在迭代过程中由于动态注册新Bean定义而导致的并发修改问题。
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
		// 实例化非懒加载的单例Bean
		for (String beanName : beanNames) {
			//获取BeanDefinition的定义
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			//遍历所有Bean名称,检查每个Bean是否满足以下条件:不是抽象BeanDefinition(!bd.isAbstract())。是单例BeanDefinition(bd.isSingleton())。不是懒加载 (!bd.isLazyInit())
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
			//如果是 FactoryBean 类型,则进一步判断是否需要立即初始化(通过 SmartFactoryBean.isEagerInit() 方法)。
				if (isFactoryBean(beanName)) {
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						//对于 FactoryBean 类型的Bean,首先获取其对应的工厂Bean实例。如果工厂Bean实现了 SmartFactoryBean 接口,则判断是否需要立即初始化(isEagerInit)。如果启用了安全管理器(System.getSecurityManager()),则通过 AccessController.doPrivileged 提升权限来调用 isEagerInit 方法。如果需要立即初始化,则调用 getBean(beanName) 实例化该Bean。
						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 {
					//从这开始实例化
					getBean(beanName);
				}
			}
		}
		// 再次遍历所有Bean名称,检查是否有实现了 SmartInitializingSingleton 接口的Bean。如果存在,则调用其 afterSingletonsInstantiated 方法,通知这些Bean所有单例Bean已经完成实例化。如果启用了安全管理器,则通过 AccessController.doPrivileged 提升权限来调用 afterSingletonsInstantiated 方法。
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	}

确保所有非懒加载的单例Bean在容器启动时被提前实例化。提供一个扩展点(SmartInitializingSingleton),允许开发者在所有单例Bean实例化完成后执行自定义逻辑。

继续点进getBean(beanName);方法,来到了AbstractBeanFactory#getBean(String name),点进doGetBean(name, null, null, false);方法,来到了AbstractBeanFactory#getBean(String name)的具体逻辑。

3、AbstractBeanFactory#getBean(String name)

	protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {
		//得到Bean的名字,如果指定的是别名,将别名转换为规范的 Bean 名称
		String beanName = transformedBeanName(name);
		Object bean;

		// Eagerly check singleton cache for manually registered singletons.
		//从缓存中获取单利的Bean,对于单利只会创建一次,创建好之后就会缓存到map中
		//默认情况下Bean都是迫切加载的,在容器启动的过程中就实例化好缓存到Map中
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			if (logger.isTraceEnabled()) {
				//判断bean是否在  singletonsCurrentlyInCreation set集合中,该集合中存储的是正在创建的单利Bean
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
					logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
			//获取 Bean 实例的对象,主要是完成 FactoryBean 的相关处理
			//即:naem是是以  $ 开头 ,就返回FactoryBean工厂
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}
		else {
			//代码走到这里,说明单利缓存的map中是没有正在创建的bean。
			// Fail if we're already creating this bean instance:
			// We're assumably within a circular reference.
			//如果缓存中没有单利Bean,但是缓存中有一个多利的Bean,目前正在创建,由于循环依赖问题,抛出异常
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// Check if bean definition exists in this factory.
			//得到容器IOC工厂
			BeanFactory parentBeanFactory = getParentBeanFactory();
			//通过beanName检查,如果容器中不包含这个Bean
			//如果容器中没有Bean,沿着继承体系交给父级去找
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
				//得到Bean的原始名字,将别名解析为规范名称
				String nameToLookup = originalBeanName(name);
				if (parentBeanFactory instanceof AbstractBeanFactory) {
					//根据名字,类型,参数找Bean
					return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
							nameToLookup, requiredType, args, typeCheckOnly);
				}
				else if (args != null) {
					//委托父工厂去找Bean , 根据名字和参数
					// Delegation to parent with explicit args.
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				else if (requiredType != null) {
					// 无参数 -> 委托给标准的 getBean 方法,根据名字和类型
					// No args -> delegate to standard getBean method.
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
				else {
					//根据名字找Bean
					return (T) parentBeanFactory.getBean(nameToLookup);
				}
			}
			//创建Bean是否要类型检查
			if (!typeCheckOnly) {
				//标记Bean被创建
				markBeanAsCreated(beanName);
			}
			try {
				//合并Bean,主要解决Bean继承时子类和父类的公共属性
				RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);
				// Guarantee initialization of beans that the current bean depends on.
				//保证当前 bean 所依赖的 bean 的初始化。
				String[] dependsOn = mbd.getDependsOn();
				//如果当前Bean依赖了其他Bean
				if (dependsOn != null) {
					for (String dep : dependsOn) {
						//
						if (isDependent(beanName, dep)) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
						}
						//为给定的 bean 注册一个依赖 bean
						registerDependentBean(dep, beanName);
						try {
							//递归,从容器中获取依赖的Bean
							getBean(dep);
						}
						catch (NoSuchBeanDefinitionException ex) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
						}
					}
				}

				// Create bean instance.
				//创建单利Bean
				if (mbd.isSingleton()) {
					//根据Bean名字获取单利Bean,这里是真正创建Bean的地方,通过ObjectFactory创建
                      //这里是匿名内部类
					sharedInstance = getSingleton(beanName, () -> {
						try {
							//创建Bean
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							// Explicitly remove instance from singleton cache: It might have been put there
							// eagerly by the creation process, to allow for circular reference resolution.
							// Also remove any beans that received a temporary reference to the bean.
							//销毁实例,从缓存的map中清除单利Bean
							destroySingleton(beanName);
							throw ex;
						}
					});
					//返回bean实例,主要处理FactoryBean相关
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}
				//如果是多例
				else if (mbd.isPrototype()) {
					// It's a prototype -> create a new instance.
					//如果是prototype模式,每次都会创建新的实例
					Object prototypeInstance = null;
					try {
						beforePrototypeCreation(beanName);
						//创建指定 Bean 对象实例 ,如果是prototype模式,每次都会创建新的实例
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						//默认实现将原型标记为不再创建
						afterPrototypeCreation(beanName);
					}
					//返回bean实例,主要处理FactoryBean相关
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}

				else {
					String scopeName = mbd.getScope();
					//如果不是单利,不是多利,Bean没有 scope属性,则不合法
					if (!StringUtils.hasLength(scopeName)) {
						throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
					}
					Scope scope = this.scopes.get(scopeName);
					if (scope == null) {
						throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
					}
					try {
						Object scopedInstance = scope.get(beanName, () -> {
							beforePrototypeCreation(beanName);
							try {
								return createBean(beanName, mbd, args);
							}
							finally {
								afterPrototypeCreation(beanName);
							}
						});
						bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					}
					catch (IllegalStateException ex) {
						throw new BeanCreationException(beanName,
								"Scope '" + scopeName + "' is not active for the current thread; consider " +
								"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
								ex);
					}
				}
			}
			catch (BeansException ex) {
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
		}
		//检查所需类型是否与实际 bean 实例的类型匹配。
		// Check if required type matches the type of the actual bean instance.
		if (requiredType != null && !requiredType.isInstance(bean)) {
			try {
				T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
				if (convertedBean == null) {
					throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
				}
				return convertedBean;
			}
			catch (TypeMismatchException ex) {
				if (logger.isTraceEnabled()) {
					logger.trace("Failed to convert bean '" + name + "' to required type '" +
							ClassUtils.getQualifiedName(requiredType) + "'", ex);
				}
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
		}
		return (T) bean;
	}

如果当前是多例,他就走单例的逻辑,如果当前的Bean的定义是单例就走单例的逻辑。

4、DefaultSingletonBeanRegistry#getSingleton(String beanName, ObjectFactory<?> singletonFactory)

值得注意的一点是,getSingleton(beanName, () -> {return createBean(beanName, mbd, args);}) ,这段代码使用了函数式编程,这里先运行了getSingleton()方法里面的逻辑,里面的singletonFactory再调用createBean(beanName, mbd, args);进行创建具有真正意义的Bean,这里的Bean就不是BeanDefinition对象

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		//检查参数的有效性:
		Assert.notNull(beanName, "Bean name must not be null");
		//使用 singletonObjects 作为锁对象来同步,确保对单例对象缓存的访问是线程安全的。
		synchronized (this.singletonObjects) {
		//从单例缓存中获取对应的 bean 实例。如果实例已经存在,则直接返回该实例。
			Object singletonObject = this.singletonObjects.get(beanName);
			if (singletonObject == null) {
			//防止在单例销毁过程中创建新的单例 bean,避免不一致的状态。
				if (this.singletonsCurrentlyInDestruction) {
					throw new BeanCreationNotAllowedException(beanName,
							"Singleton bean creation not allowed while singletons of this factory are in destruction " +
							"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
				}
				//日志记录
				if (logger.isDebugEnabled()) {
					logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
				}
				//准备创建单例之前的钩子方法。
				beforeSingletonCreation(beanName);
				boolean newSingleton = false;
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<>();
				}
				try {
					//调用提供的 ObjectFactory 来创建 bean 实例。这个ObjectFactory 调用的是上面createBean(beanName, mbd, args);里面的逻辑创建。
					singletonObject = singletonFactory.getObject();
					newSingleton = true;
				}
				catch (IllegalStateException ex) {
					// Has the singleton object implicitly appeared in the meantime ->
					// if yes, proceed with it since the exception indicates that state.
					singletonObject = this.singletonObjects.get(beanName);
					if (singletonObject == null) {
						throw ex;
					}
				}
				//处理 IllegalStateException,检查在异常发生期间单例对象是否已经被创建。
				//处理 BeanCreationException,如果有 suppressed 异常,将其记录为相关原因。
				catch (BeanCreationException ex) {
					if (recordSuppressedExceptions) {
						for (Exception suppressedException : this.suppressedExceptions) {
							ex.addRelatedCause(suppressedException);
						}
					}
					throw ex;
				}
				finally {
					if (recordSuppressedExceptions) {
						this.suppressedExceptions = null;
					}
					//清理被抑制的异常记录。
					//创建单例之后的钩子方法。
					afterSingletonCreation(beanName);
				}
				if (newSingleton) {
					//如果创建了新的单例对象,将其注册到单例缓存中。
					addSingleton(beanName, singletonObject);
				}
			}
			return singletonObject;
		}
	}

getSingleton 方法在 Spring 框架中负责管理单例 bean 的生命周期,通过 ObjectFactory 延迟加载单例对象,并确保其创建过程是线程安全的。此方法不仅负责实例化,还包括对异常的处理和单例对象的缓存管理,是 Spring IOC 容器中单例管理的核心部分。

4.1、放入缓存池DefaultSingletonBeanRegistry#addSingleton

createBean(beanName, mbd, args);创建的Bean返回回来后,就通过addSingleton(beanName, singletonObject);方法放入单例缓存池中。后续需要Bean,就直接从这里面拿就是了,但是只适用于单例Bean

	/**
	 * 将给定的单例对象添加到此工厂的单例缓存中。
	 * <p>To be called for eager registration of singletons.
	 * @param beanName 指定了bean的名称
	 * @param singletonObject 单例对象
	 */
	protected void addSingleton(String beanName, Object singletonObject) {
		synchronized (this.singletonObjects) {
			//缓存单例对象
			this.singletonObjects.put(beanName, singletonObject);
			//清理单例工厂缓存
			this.singletonFactories.remove(beanName);
			//清理早期单例对象缓存:
			this.earlySingletonObjects.remove(beanName);
			//注册单例名称
			this.registeredSingletons.add(beanName);
		}
	}

我们再来看看单例bean的缓存池,就是一个线程安全的ConcurrentHashMap。

//Cache of singleton objects: bean name to bean instance.
//单例对象的缓存:bean名称到bean实例。
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

addSingleton 方法是 Spring 框架中 DefaultSingletonBeanRegistry 类的一部分。这个方法的主要作用是在单例对象被创建后,将其缓存到单例对象的缓存中,并进行相关的清理和管理操作。

5、AbstractBeanFactory#createBean(String name)

我们点进sharedInstance = getSingleton(beanName, () -> {try {return createBean(beanName, mbd, args);}中的createBean(beanName, mbd, args)方法,再来看看如何创建的一个Bean对象。具体的实现是交给AbstractBeanFactory的实现类AbstractAutowireCapableBeanFactory来实现。

@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {
		//如果日志级别设置为 TRACE,记录正在创建 bean 实例的日志信息。
		if (logger.isTraceEnabled()) {
			logger.trace("Creating instance of bean '" + beanName + "'");
		}
		RootBeanDefinition mbdToUse = mbd;

		// Make sure bean class is actually resolved at this point, and
		// clone the bean definition in case of a dynamically resolved Class
		// which cannot be stored in the shared merged bean definition.
		//确保 bean 类已解析。如果解析的类不能存储在共享的合并 bean 定义中,则克隆 bean 定义并设置解析的类。
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		//准备方法重写。
		try {
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
			// 实例化前后置处理
			//通过 BeanPostProcessor 进行实例化前的处理,如果处理器返回一个代理对象,则直接返回该对象。
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
					"BeanPostProcessor before instantiation of bean failed", ex);
		}

		try {
			//调用 doCreateBean 方法执行 bean 的实际创建过程。
			//通过 logger 记录创建完成的日志。
			//处理所有在创建过程中可能抛出的异常。
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isTraceEnabled()) {
				logger.trace("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
	}

主要的方法:

  • resolveBeanClass: 解析 bean 的类信息。 prepareMethodOverrides:
  • 准备和验证方法覆盖(主要用于支持 lookup-method 和 replace-method)。
  • resolveBeforeInstantiation: 允许 BeanPostProcessor 在实例化之前返回一个代理对象。
  • doCreateBean: 负责 bean 的实际创建过程,包括实例化、依赖注入、初始化等。

createBean 方法负责管理 Spring Bean 的创建过程,确保每个 bean 实例在被应用程序使用之前都经过完整的生命周期管理,包括类解析、方法覆盖检查、实例化前后处理、实际实例化和异常处理等过程。它是 Spring 框架中 bean 生命周期管理的重要组成部分,为应用程序提供了灵活的依赖注入和生命周期管理机制。

6、AbstractBeanFactory#doCreateBean(beanName, mbdToUse, args);

doCreateBean方法负责 bean 的实际创建过程,包括实例化、依赖注入、初始化等。这个方法里面能清楚直接明显看到Bean的生命周期。

这个方法非常重要。

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			//检查并从缓存中移除工厂实例缓存,用于单例。
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			//调用 createBeanInstance 方法实例化 bean。
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		//解析和缓存 bean 的类型。
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}

		// Allow post-processors to modify the merged bean definition.
		//应用后处理器以修改合并的 bean 定义,确保每个 bean 只处理一次。
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				mbd.postProcessed = true;
			}
		}

		// Eagerly cache singletons to be able to resolve circular references
		// even when triggered by lifecycle interfaces like BeanFactoryAware.
		//如果允许循环引用,则提前暴露 bean 的早期引用,可能通过创建代理来解决循环依赖。
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isTraceEnabled()) {
				logger.trace("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			//调用 populateBean 方法进行属性填充(依赖注入)。
			populateBean(beanName, mbd, instanceWrapper);
			//调用 initializeBean 方法进行初始化,包括应用 BeanPostProcessors。
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		catch (Throwable ex) {
			if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
				throw (BeanCreationException) ex;
			}
			else {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
			}
		}
		//循环引用检查和处理:
		if (earlySingletonExposure) {
			Object earlySingletonReference = getSingleton(beanName, false);
			if (earlySingletonReference != null) {
				if (exposedObject == bean) {
					exposedObject = earlySingletonReference;
				}
				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
					String[] dependentBeans = getDependentBeans(beanName);
					Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
					for (String dependentBean : dependentBeans) {
						if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
							actualDependentBeans.add(dependentBean);
						}
					}
					if (!actualDependentBeans.isEmpty()) {
						throw new BeanCurrentlyInCreationException(beanName,
								"Bean with name '" + beanName + "' has been injected into other beans [" +
								StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
								"] in its raw version as part of a circular reference, but has eventually been " +
								"wrapped. This means that said other beans do not use the final version of the " +
								"bean. This is often the result of over-eager type matching - consider using " +
								"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
					}
				}
			}
		}

		// Register bean as disposable.
		try {
			//注册 bean 为可销毁的对象,以便在容器关闭时进行销毁。
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}
		//返回最终的 bean 实例(可能是代理对象)。
		return exposedObject;
	}

doCreateBean 方法是 Spring Bean 生命周期管理的核心,它处理从 bean 实例化到初始化的全过程,包括依赖注入、后处理器应用、解决循环引用和注册销毁回调等。通过这个方法,Spring 确保每个 bean 都能按照配置和依赖正确创建,并在需要时参与到应用程序的生命周期管理中。

这个篇章只写这个方法的实例化。

7、createBeanInstance(beanName, mbd, args)

我们点进instanceWrapper = createBeanInstance(beanName, mbd, args);方法,来到了AbstractAutowireCapableBeanFactory#createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) 方法。

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		// 通过 resolveBeanClass 确保 bean 类在此时已被解析。
		Class<?> beanClass = resolveBeanClass(mbd, beanName);
		//如果 bean 类不是公共的且配置不允许非公共访问,抛出异常。
		if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
		}
		//如果有 Supplier 提供实例,则通过 obtainFromSupplier 方法获取实例。
		Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
		if (instanceSupplier != null) {
			return obtainFromSupplier(instanceSupplier, beanName);
		}
		if (mbd.getFactoryMethodName() != null) {
			//如果定义了工厂方法,则通过 instantiateUsingFactoryMethod 方法实例化 bean。
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}
		//如果构造函数或工厂方法已经解析,检查是否需要自动装配。
		//如果需要则通过 autowireConstructor,否则直接实例化。
		boolean resolved = false;
		boolean autowireNecessary = false;
		if (args == null) {
			synchronized (mbd.constructorArgumentLock) {
				if (mbd.resolvedConstructorOrFactoryMethod != null) {
					resolved = true;
					autowireNecessary = mbd.constructorArgumentsResolved;
				}
			}
		}
		if (resolved) {
			if (autowireNecessary) {
				return autowireConstructor(beanName, mbd, null, null);
			}
			else {
				return instantiateBean(beanName, mbd);
			}
		}

		//检查是否有候选构造函数可以用于自动装配。
		//如果有,使用构造函数自动装配。
		// Candidate constructors for autowiring?
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
			return autowireConstructor(beanName, mbd, ctors, args);
		}
		// Preferred constructors for default construction?
		//如果有首选构造函数,则使用它进行构造。
		ctors = mbd.getPreferredConstructors();
		if (ctors != null) {
			return autowireConstructor(beanName, mbd, ctors, null);
		}
		// No special handling: simply use no-arg constructor.
		//如果没有特殊处理需求,则使用无参构造函数实例化 bean。
		return instantiateBean(beanName, mbd);
	}

Spring 提供了多种策略来实例化 Bean,主要包括:

  • 无参构造函数:这是最常见的方法,通过反射调用无参构造函数来创建 Bean 实例。 工厂方法:通过指定工厂方法来创建 Bean
  • 实例,工厂方法可以是静态的也可以是实例方法。 Supplier:从 Spring 5 开始,可以使用 Supplier
  • 接口来提供自定义的实例化逻辑。

我们直接看最后一个方法return instantiateBean(beanName, mbd);

instantiateBean 方法是 Spring 框架中 AbstractAutowireCapableBeanFactory 类的一部分,用于实例化一个 bean 对象。这个方法采用一个简单的方式通过无参构造函数来创建 bean 实例。

	protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
		try {
			Object beanInstance;
			//如果系统中存在安全管理器(System.getSecurityManager() 不为 null),则使用 AccessController.doPrivileged 执行实例化操作。这是为了在受限环境中安全地执行潜在的受限操作。
			//getInstantiationStrategy().instantiate(mbd, beanName, this):调用实例化策略的 instantiate 方法来创建 bean 实例。默认的策略通常是使用反射调用无参构造函数。
			if (System.getSecurityManager() != null) {
				beanInstance = AccessController.doPrivileged(
						(PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),
						getAccessControlContext());
			}
			else {
				beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
			}
			//BeanWrapper:创建一个 BeanWrapper 实例,用于包装新创建的 bean 实例。BeanWrapper 是 Spring 提供的一个工具类,用于对 bean 属性进行操作。
			//初始化 BeanWrapper:调用 initBeanWrapper(bw) 初始化 BeanWrapper,通常涉及设置一些默认的属性编辑器,以帮助处理属性的类型转换。
			BeanWrapper bw = new BeanWrapperImpl(beanInstance);
			initBeanWrapper(bw);
			return bw;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
		}
	}

instantiateBean 方法是 Spring 框架中用于通过无参构造函数创建bean实例的基本方法。它利用 InstantiationStrategy 来抽象具体的实例化过程,并通过 BeanWrapper 来管理 bean 实例的属性,这为后续的属性填充和初始化步骤做好准备。此方法确保了在受限环境中安全地执行实例化操作,并为异常情况提供了统一的处理机制。

8、SimplelnstantiationStrategy#instantiate()

我们继续往下点getInstantiationStrategy().instantiate(mbd, beanName, this);,通过InstantiationStrategy的实现类SimplelnstantiationStrategy来调用构造方法实现。

	@Override
	public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
		// Don't override the class with CGLIB if no overrides.
		//检查 RootBeanDefinition 中是否有方法覆盖(method overrides)。如果没有方法覆盖,则不需要使用 CGLIB 代理来创建 bean。
		if (!bd.hasMethodOverrides()) {
			Constructor<?> constructorToUse;
			//为了线程安全,使用 constructorArgumentLock 对构造函数的选择进行同步。
			synchronized (bd.constructorArgumentLock) {
				constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
				if (constructorToUse == null) {
				//如果构造函数还没有解析,则获取 bean 类的无参构造函数。
					final Class<?> clazz = bd.getBeanClass();
					//如果类是接口或没有找到无参构造函数,则抛出 BeanInstantiationException。
					if (clazz.isInterface()) {
						throw new BeanInstantiationException(clazz, "Specified class is an interface");
					}
					try {
						if (System.getSecurityManager() != null) {
							constructorToUse = AccessController.doPrivileged(
									(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
						}
						else {
							constructorToUse = clazz.getDeclaredConstructor();
						}
						bd.resolvedConstructorOrFactoryMethod = constructorToUse;
					}
					catch (Throwable ex) {
						throw new BeanInstantiationException(clazz, "No default constructor found", ex);
					}
				}
			}
			//使用 BeanUtils.instantiateClass 方法调用选定的构造函数来创建 bean 实例。
			return BeanUtils.instantiateClass(constructorToUse);
		}
		else {
			// 如果存在方法覆盖,则需要生成一个 CGLIB 子类来实现方法注入。调用 instantiateWithMethodInjection 方法进行处理。
			return instantiateWithMethodInjection(bd, beanName, owner);
		}
	}

这个方法中做了一个判断如果Bean有方法被覆盖,就使用JDK反射来创建Bean的实例,否则使用CGLIB来实例化。 CGLIB调用的是子类 CglibSubclassingInstantiationStrategy 来完成的 , 如果一个类没有接口,就只能使用CGLIB

确保在适当的情况下使用最简单的方式来创建 bean 实例,同时支持复杂的场景如方法覆盖,通过使用 CGLIB 来动态生成代理类。这种设计使得 Spring 能够灵活地管理 bean 的创建和生命周期,同时支持多种复杂的 bean 配置需求。

9、BeanUtils.instantiateClass(constructorToUse);

再来看BeanUtils.instantiateClass(constructorToUse);的方法.
instantiateClass 方法是 Spring 框架中的一个实用方法,用于通过反射调用构造函数来创建类的实例。

public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
		//检查构造函数的非空性:
		Assert.notNull(ctor, "Constructor must not be null");
		try {
		//调用 makeAccessible 方法确保即使是非公共构造函数也可以被调用。这在反射中是一个常用的步骤,以绕过 Java 的访问控制。
			ReflectionUtils.makeAccessible(ctor);
			//检查当前环境中是否存在 Kotlin 反射库,并且构造函数的声明类是否是 Kotlin 类型。如果是 Kotlin 类,使用 KotlinDelegate.instantiateClass 方法来处理 Kotlin 特有的实例化需求。
			if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {
				return KotlinDelegate.instantiateClass(ctor, args);
			}
			else {
				//获取构造函数的参数类型数组。
				Class<?>[] parameterTypes = ctor.getParameterTypes();
				//确保传入的参数数量不超过构造函数参数的数量。
				Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters");
				Object[] argsWithDefaultValues = new Object[args.length];
				//遍历传入的参数数组。如果参数为 null 且对应的参数类型是基本类型,则从 DEFAULT_TYPE_VALUES 中获取默认值。否则,直接使用传入的参数值。
				for (int i = 0 ; i < args.length; i++) {
					if (args[i] == null) {
						Class<?> parameterType = parameterTypes[i];
						argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);
					}
					else {
						argsWithDefaultValues[i] = args[i];
					}
				}
				//通过无参构造来创建一个实例。。
				return ctor.newInstance(argsWithDefaultValues);
			}
		}
	}

五、总结

实例化策略
Spring 提供了多种策略来实例化 Bean,主要包括:

  • 无参构造函数:这是最常见的方法,通过反射调用无参构造函数来创建 Bean 实例。 工厂方法:通过指定工厂方法来创建 Bean
  • 实例,工厂方法可以是静态的也可以是实例方法。
  • Supplier:从 Spring 5 开始,可以使用 Supplier接口来提供自定义的实例化逻辑。

构造函数解析

  • 自动装配构造函数:Spring 可以通过构造函数自动装配机制,根据构造函数的参数类型和 Bean 定义中的配置自动选择合适的构造函数
  • 参数类型匹配:Spring 通过反射检查构造函数参数类型,并提供适当的参数(包括默认值)进行实例化。

方法覆盖和 CGLIB

  • 方法覆盖:Spring 支持通过 CGLIB 动态代理实现方法覆盖(例如 lookup-method 和 replace-method),这需要生成子类来覆盖特定方法。

BeanWrapper

  • 属性管理:实例化后,Spring 使用 BeanWrapper 来封装 Bean 实例,以方便后续的属性填充和类型转换。

安全管理

  • 安全性:在有安全管理器的环境中,Spring 使用 AccessController.doPrivileged 来执行实例化操作,确保在受限环境中安全地进行反射调用。

解决循环依赖

  • 提前暴露引用:为了处理循环依赖,Spring 可在实例化过程中提前暴露 Bean 的引用,允许其他 Bean 注入一个早期引用。

文章结束,喜欢就给个一键三连吧,你的肯定是我最大的动力,点赞上一千我就是脑瘫也出下章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小Ti客栈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值