Spring深度学习:Bean生命周期及源码解析


Spring深度学习:Bean生命周期及源码解析

一、序言

大家经常戏称Java工程师为Spring工程师,毫无疑问,这句话体现出Spring框架在Java开发中的重要性和普及度。

本文小豪将带大家深度学习Spring Bean相关知识,包括Bean的生命周期及Bean创建过程的底层源码,学习过程中不仅仅是了解Spring Bean的工作原理,更重要的是学会理解框架的底层逻辑,从而提升我们的思维能力。

文章最后附有流程图,进一步帮我们梳理业务逻辑

二、定义Bean

总所周知,Bean就是Spring应用的Java对象,它们被Spring IOC容器创建,装配和管理。

Spring中有多种方式可以定义Bean,我们常用的,大致包括以下几种:
在这里插入图片描述

  1. 声明式:通过配置的方式进行Bean的定义,更为便捷

    • XML配置标签:在XML配置文件使用<bean>标签
    • @Bean注解:在配置类里面,使用@Bean注解
    • @Component注解:在类上添加@Component注解,包括其派生注解@Controller@Service@RestController
    • @Configuration注解:在类上添加,标识类为配置类
  2. 编程式:编写具体代码实现Bean定义的方式,更为灵活

    • 注册BeanDefinition:通过BeanDefinitionBuilder添加Bean
    • 实现FactoryBean:通过继承FactoryBean接口,重写getObject()方法生成Bean

这里我们简单了解下Spring定义Bean的方式即可,各方式具体如何应用不作为本文重点

三、Bean生命周期

在源码分析之前,咱们先简要聊一下关于Bean的生命周期,但想必大家已经对Bean生命周期耳熟能详了,这里让我们再回顾一下,大致包括如下阶段:
在这里插入图片描述

  1. 实例化阶段(createBeanInstance):Spring根据生成的BeanDefinition,通过反射调用Bean的构造方法来创建Bean的实例
  2. 属性注入阶段(populateBean):此时Bean还未对属性进行填充,Spring查找BeanDefinition中标注的属性,注入Bean对象需要的值
  3. 初始化阶段(initializeBean):属性注入后,Spring调用Bean的初始化方法,执行一些初始化操作
  4. 使用阶段:初始化之后,Bean对象正式创建完成,可以被注入到其它Bean中,或者被其它Bean调用
  5. 销毁阶段:Spring容器关闭时,调用Bean的销毁方法,执行清理操作

四、源码分析

在上一篇【Spring深度学习:IOC容器及源码解析】小豪带大家了解了Spring IOC容器创建refresh()方法的工作过程,同时着重分析了obtainFreshBeanFactory()方法的作用,通过该方法完成初始化BeanFactory,加载并解析xml配置文件并生成BeanDefinition,最后将BeanName与生成的BeanDefinition放入BeanDefinitionMap完成注册。

BeanDefinition仅仅是对Bean信息的定义,具体如何通过BeanDefinition转化为最终的Bean对象,Bean是怎样创建和注入属性的,以及在这个过程中发生了什么,目前我们暂不清楚,从上篇文章中初步了解到 refresh()方法中finishBeanFactoryInitialization()方法进行实例化所有非懒加载的单例Bean,本文继续将深入学习,剖析核心方法finishBeanFactoryInitialization()的工作过程,有关Bean对象的构造、依赖注入、初始化、AOP等均在此方法中完成:

// 实例化所有非懒加载的单例Bean
finishBeanFactoryInitialization(beanFactory);

1.finishBeanFactoryInitialization

进入finishBeanFactoryInitialization()方法,具体源码如下:

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {

		// 判断BeanFactory中包含ConversionService的bean,并且类型为ConversionService,那么将它们设置为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));
		}

		// 注册嵌入式解析器
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// 获取所有实现LoadTimeWeaverAware接口的类,进行初始化,加载时织入
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		// 进行使用临时ClassLoader进行类型匹配
		beanFactory.setTempClassLoader(null);

		// 冻结所有的beanDefinition信息,不允许修改,即将进行实例化bean对象
		beanFactory.freezeConfiguration();

		// (核心)实例化所有剩下的非懒加载单例
		beanFactory.preInstantiateSingletons();
	}

在本方法中,首先做了实例化前的一些准备工作,包括设置属性转化、注册嵌入式解析器、冻结beanDefinition等,在这里我们只需要着重分析beanFactory.preInstantiateSingletons()方法,它会实例化所有剩下的非懒加载单例。

2.preInstantiateSingletons

进入DefaultListableBeanFactory类下的preInstantiateSingletons()方法,具体源码如下:

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

		// 创建beanDefinitionNames的副本,将原始beanDefinitionNames数据拷贝到List
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// 遍历所有beanDefinition,进行初始化
		for (String beanName : beanNames) {
			// 将所有BeanDefinition合并为统一的RootBeanDefinition,Spring内部使用的其实都是RootBeanDefinition对象
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			// 非抽象类 & 单例 & 非懒加载
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				// 判断是否为工厂Bean
				if (isFactoryBean(beanName)) {
					// 工厂Bean需要加前缀"&"符号
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					// 工厂Bean优先实例化自己,工厂Bean内部的getObject()方法默认懒加载
					if (bean instanceof FactoryBean) {
						FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						// 如果实现了SmartFactoryBean接口,并且设置isEagerInit()方法返回true,就会立马实例化内部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实例化之后执行,Spring提供的扩展点
		for (String beanName : beanNames) {
			// 获取单例Bean,上一步getBean()方法已完成所有单例Bean的实例化
			Object singletonInstance = getSingleton(beanName);
			// 判断是否实现SmartInitializingSingleton接口
			if (singletonInstance instanceof SmartInitializingSingleton) {
				SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					// 执行自定义的具体逻辑
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	}

查看源码发现,preInstantiateSingletons()方法大致做了如下工作:

  1. 获取待初始化的 BeanDefinition名称:首先获取所有需要实例化的Bean的名称。包括普通的 Bean以及工厂 Bean(实现了 FactoryBean 接口)。
  2. 遍历 bean 名称并初始化
    • 合并BeanDefinition为统一的RootBeanDefinition
    • 判断Bean是否为工厂 Bean,如果 Bean 是工厂Bean,进一步判断工厂 BeanisEagerInit 属性,决定是否立即实例化,如果需要立即初始化,Spring会调用工厂BeangetObject() 方法来获取具体的Bean实例。如果不是工厂Bean,直接获取具体的Bean实例。
  3. 触发单例bean实例化之后的回调:如果Bean实现了 SmartInitializingSingleton 接口,Spring容器会在所有单例Bean都实例化完成回调BeanafterSingletonsInstantiated() 方法。

综上分析,整个preInstantiateSingletons()方法逻辑也比较简单,获取所有待实例化的Bean名称,依次进行遍历,如果是非抽象类 & 单例 & 非懒加载的Bean,则会进行实例化,同时在实例化完成之后进行Bean实例化的后置处理,其中getBean()为具体的实例化方法,我们进一步跟入方法内部。

3.getBean

进入AbstractBeanFactory类的getBean()方法,具体源码如下:

public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}

发现getBean()方法逻辑仅调用当前类的doGetBean()方法,在之前我们也分析过Spring框架中do开头的方法为具体的做事方法,在进入doGetBean()方法之前,我们先暂停一下,回顾我们Spring IOC容器的入口:

public static void main(String[] args) {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring-config.xml");
		User user = (User) applicationContext.getBean("user");
	}

这里获取Bean对象时是通过调用applicationContext对象的getBean(String name)方法,是否和上文中的getBean()方法是同一个呢,我们进入AbstractApplicationContext类的getBean()方法,源码如下:

public <T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException {
		assertBeanFactoryActive();
		return getBeanFactory().getBean(name, requiredType);
	}

发现它又调用 BeanFactory 中的 getBean() 方法,在上一篇Spring IOC容器学习过程中,我们分析出BeanFactory默认是使用DefaultListableBeanFactory,但DefaultListableBeanFactory没有对getBean(String name) 方法的重写,而DefaultListableBeanFactory类继承自AbstractAutowireCapableBeanFactory类,AbstractAutowireCapableBeanFactory类又继承自AbstractBeanFactory 类,最终,发现使用的都是AbstractBeanFactory类的getBean()方法。

我们继续进入AbstractBeanFactory类的doGetBean()方法,具体源码如下:

protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {

		// 转化名称,name统一转化为beanName,因为name可能是别名
		String beanName = transformedBeanName(name);
		Object bean;

		// 检查缓存里是否有当前单例(三级缓存)
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			if (logger.isDebugEnabled()) {
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
					logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
			// 将缓存对象返回出去
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {
			// 判断原型模式下是否存在循环依赖问题,Spring不允许原型模式下出现循环依赖
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// 判断是否存在父工厂,检查父工厂是否已经实例化过该Bean,避免重复实例化单例Bean
			BeanFactory parentBeanFactory = getParentBeanFactory();
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// 根据name获取beanName,如果name以&开头,就会返回&+beanName
				String nameToLookup = originalBeanName(name);
				if (parentBeanFactory instanceof AbstractBeanFactory) {
					return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
							nameToLookup, requiredType, args, typeCheckOnly);
				}
				else if (args != null) {
					// Delegation to parent with explicit args.
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				else {
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
			}

			// 是否仅是进行类型检查
			if (!typeCheckOnly) {
				markBeanAsCreated(beanName);
			}

			try {
				// 合并BeanDefinition
				RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				// 检查是否为抽象Bean
				checkMergedBeanDefinition(mbd, beanName, args);

				// 判断当前创建的Bean是否有依赖的Bean
				String[] dependsOn = mbd.getDependsOn();
				if (dependsOn != null) {
					for (String dep : dependsOn) {
						// 检查是否存在depends-on循环依赖,存在则抛异常
						if (isDependent(beanName, dep)) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
						}
						// 不存在depends-on循环依赖就会进行注册
						registerDependentBean(dep, beanName);
						try {
							// 优先实例化依赖的Bean,递归调用
							getBean(dep);
						}
						catch (NoSuchBeanDefinitionException ex) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
						}
					}
				}

				// 开始实例化当前的单例Bean
				if (mbd.isSingleton()) {
					// 通过getSingleton(beanName,singletonFactory)方法获取实例对象(重点)
					// 使用lambda表达式来实现匿名内部类,传入singletonFactory参数
					sharedInstance = getSingleton(beanName, () -> {
						try {
							// 核心方法,这里完成创建Bean对象(重点)
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							// 如果创建过程中发生异常,则会进行销毁
							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

				// 实例化多例Bean
				else if (mbd.isPrototype()) {
					Object prototypeInstance = null;
					try {
						beforePrototypeCreation(beanName);
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						afterPrototypeCreation(beanName);
					}
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}

				// 实例化其它作用域的Bean
				else {
					String scopeName = mbd.getScope();
					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是否需要进行转化
		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.isDebugEnabled()) {
					logger.debug("Failed to convert bean '" + name + "' to required type '" +
							ClassUtils.getQualifiedName(requiredType) + "'", ex);
				}
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
		}
		return (T) bean;
	}

查看源码发现,doCreateBean()方法逻辑内容比较多,大致分为以下几步:

  1. 解析Bean名称:Spring解析传入的 name 属性,将其转换为标准的Bean名称 beanName
  2. 获取单例Bean实例:从缓存中获取单例Bean实例:
    • 如果已经在三级缓存中存在单例Bean缓存,直接返回缓存中的Bean实例。
  3. 条件判断:进行一些实例化前的条件判断,包括判断原型模式下是否存在循环依赖问题,判断是否存在父工厂,判断是否仅进行类型检查
  4. 循环依赖解析:判断是否存在循环依赖,先解析依赖关系,优先实例化依赖的Bean,递归调用。
  5. 实例化Bean
    • 实例化单例Bean:调用getSingleton()方法,传入beanNamelambda表达式获取实例对象;
    • 实例化多例Bean
    • 实例化其它作用域的Bean
  6. 类型转化:判断Bean是否需要进行类型转化。

由此可知,doCreateBean()方法首先定义Bean的统一名称,然后再次尝试去缓存获取当前单例Bean,其次进行部分条件判断并解析依赖关系(优先实例化依赖的Bean),最后根据类型依次实例化单例Bean、多例Bean和其它作用域的Bean

doCreateBean()方法逻辑中,存在两个同名的重载方法,分别是getSingleton(String beanName, boolean allowEarlyReference)getSingleton(String beanName, ObjectFactory<?> singletonFactory)方法。

首先doCreateBean()方法会调用getSingleton(String beanName, boolean allowEarlyReference)方法检查单例缓存中是否已经存在该Bean,如果没有则判断当前Bean的作用域类型是否是单例的,如果是单例会再次调用重载方法getSingleton(String beanName, ObjectFactory<?> singletonFactory),实例化单例Bean

后续我们需要重点关注实例化单例BeangetSingleton(String beanName, ObjectFactory<?> singletonFactory)方法中singletonFactory参数,以及它的核心方法createBean()

我们先分析第一个重载方法getSingleton(String beanName, boolean allowEarlyReference)方法,检查缓存里是否有当前单例,进入方法内部具体源码如下:

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		// 首先从一级缓存中获取对象
		Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			// 一级缓存如果为空,直接上锁
			synchronized (this.singletonObjects) {
				// 然后尝试从二级缓存中获取对象
				singletonObject = this.earlySingletonObjects.get(beanName);
				if (singletonObject == null && allowEarlyReference) {
					// 如果也为空,则从三级缓存中获取对象
					ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
					if (singletonFactory != null) {
						// 通过三级缓存生成提前曝光的Bean
						singletonObject = singletonFactory.getObject();
						// 放入二级缓存并在三级缓存中移除
						this.earlySingletonObjects.put(beanName, singletonObject);
						this.singletonFactories.remove(beanName);
					}
				}
			}
		}
		return singletonObject;
	}

观察源码发现会分别尝试从一、二、三级缓存中获取单例Bean,这里三级缓存分别对应DefaultSingletonBeanRegistry类中的三个Map集合:

/** 一级缓存 */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

/** 三级缓存 */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

/** 二级缓存 */
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

具体Spring为何使用三级缓存,这里又引申出循环依赖的问题,我们会在后续进行详细分析。先不在本篇进行讨论,我们只需要知道在实例化单例Bean之前,会依次尝试从三级缓存中获取单例Bean即可。

紧接着我们分析另一个重载方法getSingleton(String beanName, ObjectFactory<?> singletonFactory),参数一是Bean名称,参数二是使用lambda表达式来实现匿名内部类,进入方法内部,具体源码如下:

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(beanName, "Bean name must not be null");
		// 对一级缓存加锁
		synchronized (this.singletonObjects) {
			// 再次看一级缓存里有没有
			Object singletonObject = this.singletonObjects.get(beanName);
			if (singletonObject == null) {
				// 如果正在销毁,则抛异常
				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 + "'");
				}
				// 标记当前Bean正在进行创建
				beforeSingletonCreation(beanName);
				boolean newSingleton = false;
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<>();
				}
				try {
					// 调用singletonFactory的getObject()方法创建Bean
					// 其实就是执行传入的匿名内部类的createBean()方法
					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;
					}
				}
				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;
		}
	}

观察源码发现,首先会对一级缓存加锁,然后再次从一级缓存里查看有没有单例Bean,没有则会标记当前Bean正在进行创建(放入singletonsCurrentlyInCreation集合中),然后调用singletonFactorygetObject()方法创建Bean,这里其实执行的就是执行传入的匿名内部类的createBean()方法,我们再次返回doGetBean()方法实例化单例Bean的代码逻辑:

// 通过getSingleton(beanName,singletonFactory)方法获取实例对象(重点)
// 使用lambda表达式来实现匿名内部类,传入singletonFactory参数
sharedInstance = getSingleton(beanName, () -> {
	try {
		// 核心方法,这里完成创建Bean对象(重点)
		return createBean(beanName, mbd, args);
		}
	catch (BeansException ex) {
		// 如果创建过程中发生异常,则会进行销毁
		destroySingleton(beanName);
		throw ex;
	}
});
	bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

4.createBean

紧接着我们进入其核心方法createBean(),具体源码如下:

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

		if (logger.isDebugEnabled()) {
			logger.debug("Creating instance of bean '" + beanName + "'");
		}
		RootBeanDefinition mbdToUse = mbd;

		// 解析Bean的类型,防止BeanDefinition中的BeanClass没有被解析成Class
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		try {
            // 准备需要覆盖的方法,比如Lookup标签
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
            // 实例化之前判断是否需要进行代理
			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 {
			// (核心)创建Bean实例
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isDebugEnabled()) {
				logger.debug("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
		catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
			// A previously detected exception with proper bean creation context already,
			// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
		}
	}

观察源码发现,createBean()方法大致做了如下工作:

  1. Bean类型解析:解析Bean类型,以防 BeanDefinition 中的 BeanClass 尚未解析为 Class
  2. Bean实例化前的检查:判断是否需要进行代理,以及处理一些特殊情况,比如存在Lookup标签。
  3. 创建Bean实例:调用核心方法 doCreateBean 来创建bean实例。
  4. 返回Bean实例:最后返回已创建好的Bean实例。

具体逻辑也比较简单,主要就是先进行Bean实例化之前的准备工作,然后调用doCreateBean()方法创建实例,最后返回。

5.doCreateBean

接着我们继续进入do开头的doCreateBean()方法,查看详细的Bean实例创建过程,具体源码如下:

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

		// 实例化阶段:使用BeanWrapper对象进行包装
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			// 清理缓存
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		// 判断缓存是否存在,没有则实例化Bean对象
		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}

		// 允许修改合并后的BeanDefinition,提供的扩展点
		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;
			}
		}

		// 循环依赖:单例 && 支持循环引用 && 正在创建
		// 条件成立则将对象放入 singletonFactories 三级缓存
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isDebugEnabled()) {
				logger.debug("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		Object exposedObject = bean;
		try {
			// 依赖注入阶段:进行Bean的属性填充
			populateBean(beanName, mbd, instanceWrapper);
			// 初始化阶段:初始化Bean对象
			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.");
					}
				}
			}
		}

		try {
			// 注册需要销毁的Bean
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		return exposedObject;
	}

观察源码发现,doCreateBean()方法大致分为如下步骤:

  1. 实例化阶段:使用 BeanWrapper 对象进行包装,判断缓存是否存在,如果不存在,则实例化 bean 对象。
  2. BeanDefinition后置处理:提供扩展点,允许在合并后的 BeanDefinition上进行修改。
  3. 循环依赖处理:如果Bean是单例、支持循环引用,并且正在创建中,将对象放入singletonFactories三级缓存。
  4. 依赖注入阶段:进行Bean的属性填充。
  5. 初始化阶段:初始化Bean对象。
  6. 处理循环依赖的提前暴露:如果之前进行了循环依赖的提前暴露,获取提前暴露的Bean引用,根据条件更新Bean
  7. 注册需要销毁的Bean:根据需要,注册需要销毁的Bean

由此可知,doCreateBean()主要负责处理Spring中Bean的创建流程,包括实例化、属性填充、初始化关键等步骤,同时还包括处理循环依赖和提前暴露的情况。

紧接着我们再次分别深入Bean实例化、属性填充和初始化方法内部。

6.createBeanInstance

进入Bean实例化,createBeanInstance()方法,具体源码如下:

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		// 从BeanDefinition中获取到Bean的Class
		Class<?> beanClass = resolveBeanClass(mbd, beanName);

		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<?> instanceSupplier = mbd.getInstanceSupplier();
		if (instanceSupplier != null) {
			return obtainFromSupplier(instanceSupplier, beanName);
		}

		// 判断如果工厂方法不为空,则使用工厂方法实例化Bean
		if (mbd.getFactoryMethodName() != null) {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		// Shortcut when re-creating the same bean...
		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) {
				// 使用有参的构造方法,自动注入创建Bean
				return autowireConstructor(beanName, mbd, null, null);
			}
			else {
				// 使用无参的构造方法
				return instantiateBean(beanName, mbd);
			}
		}

		// 推断构造方法
		// 获取bean对应的所有构造方法
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
			// 自动注入创建Bean
			return autowireConstructor(beanName, mbd, ctors, args);
		}

		// 使用无参的构造方法
		return instantiateBean(beanName, mbd);
	}

查看源码发现,createBeanInstance()方法大致做了如下工作:

  1. 获取并判断Bean类型:从 BeanDefinition 中获取Bean的类。判断如果Bean类不是公共类且不允许访问非公共类,则抛出异常。
  2. 实例化Bean:如果存在instanceSupplier,存在则直接获取实例。否则,根据工厂方法或构造方法实例化Bean
  3. 判断是否已确定构造方法:如果已经确定构造方法,根据情况选择有参或无参构造方法。
  4. 推断构造方法:如果不确定构造方法,则获取Bean对应的所有构造方法,如果找到了进行创建Bean ,没有找到则会直接使用无参的构造方法完成Bean的初始化。

由此可知,createBeanInstance 方法负责解析Bean类、选择构造函数、执行自动装配,最终创建Bean实例并返回

7.populateBean

返回doCreateBean()方法,接着进入populateBean()方法,Bean属性注入阶段,具体源码如下:

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
		if (bw == null) {
			if (mbd.hasPropertyValues()) {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
			}
			else {
				// Skip property population phase for null instance.
				return;
			}
		}

		// 实例化之后的回调,扩展点(此时还未填充属性)
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						return;
					}
				}
			}
		}

		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

		// 注入属性
		int resolvedAutowireMode = mbd.getResolvedAutowireMode();
		if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
			// 根据名字去自动注入
			if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}
			// 根据类型去自动注入
			if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}
			pvs = newPvs;
		}

		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
		boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

		if (hasInstAwareBpps || needsDepCheck) {
			if (pvs == null) {
				pvs = mbd.getPropertyValues();
			}
			// 属性注入之后的回调,扩展点
			PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
			if (hasInstAwareBpps) {
				for (BeanPostProcessor bp : getBeanPostProcessors()) {
					if (bp instanceof InstantiationAwareBeanPostProcessor) {
						InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
						pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvs == null) {
							return;
						}
					}
				}
			}
			// 判断是否需要进行依赖检测,检查是否有依赖未被注入,确保依赖均已被正常注入
			if (needsDepCheck) {
				checkDependencies(beanName, mbd, filteredPds, pvs);
			}
		}

		if (pvs != null) {
			// 设置注入好的属性值给BeanWrapper
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
	}

查看源码发现,populateBean()方法大致做了如下工作:

  1. 属性注入前的回调:判断是否存在实例化后的回调。
  2. 执行自动装配:根据 resolvedAutowireMode 解析依赖注入的方式,将属性装配到 PropertyValues 中(分为ByName根据名字去自动注入和ByType根据类型去自动注入)。
  3. 调用后置处理器:调用 InstantiationAwareBeanPostProcessor 接口的 postProcessProperties 方法,扩展点。
  4. 依赖检查:执行 checkDependencies()方法,确保所有依赖都已经注入。
  5. 包装解析的值:设置注入好的属性值给BeanWrapper,最终完成属性的填充。

由此可知,populateBean() 方法负责解析属性依赖、执行自动装配,最终将属性填充到Bean实例中

这里我们继续进入autowireByName()方法,分析下Spring是如何根据名字去完成自动注入的:

protected void autowireByName(
			String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

		// 获取所有需要进行依赖注入的属性
		String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
		for (String propertyName : propertyNames) {
			// 判断BeanDefinition里是否存在该Bean
			if (containsBean(propertyName)) {
				// 递归调用获取到Bean
				Object bean = getBean(propertyName);
				pvs.add(propertyName, bean);
				// 注册依赖
				registerDependentBean(propertyName, beanName);
				if (logger.isDebugEnabled()) {
					logger.debug("Added autowiring by name from bean name '" + beanName +
							"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
				}
			}
			else {
				if (logger.isTraceEnabled()) {
					logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
							"' by name: no matching bean found");
				}
			}
		}
	}

可以发现,在autowireByName()方法中,首先获取所有需要进行注入的Bean名称,依次遍历,判断BeanDefinition里是否包含需要注入的Bean,然后直接根据名称递归调用getBean()方法获取到Bean,并完成依赖注入。

8.initializeBean

最后我们再次返回doCreateBean()方法,进入initializeBean()方法,Bean初始化阶段,具体源码如下:

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
		// 如果实现了AwareMethods接口则进行回调
		// 调用顺序依次为BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			invokeAwareMethods(beanName, bean);
		}

		// 调用BeanPostProcessor初始化前的方法
		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			// 调用初始化方法
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		// 调用BeanPostProcessor初始化后的方法(此过程可能会产生代理)
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}

观察源码发现,initializeBean()方法大致做了如下工作:

  1. Aware接口回调:回调实现了 AwareMethods 接口的Bean。调用顺序依次为实现BeanNameAwareBeanClassLoaderAwareBeanFactoryAware接口的Bean
  2. 调用初始化前的前置处理器:调用BeanPostProcessor初始化前的方法,在初始化之前对Bean进行增强处理。
  3. 调用初始化方法:进行调用Bean的初始化方法。
  4. 调用初始化后的后置处理器:最后,调用BeanPostProcessor初始化后的方法,在初始化之后对Bean进行处理,触发Bean的后置处理,AOP代理对象也在该阶段产生(这里说法有些不严谨,在后续讲循环依赖时,会分析哪种情况下提前生成AOP代理对象)。

由此可知,initializeBean()方法主要负责在Spring容器中初始化Bean,包括回调Aware接口、前置处理、初始化方法调用和后置处理等

五、流程图

在这里插入图片描述

六、后记

本文从Bean的定义以及Bean的生命周期开始介绍,过度到源码分析,带大家认识BeanDefinition如何从一步步被创建为Bean对象,想必大家对Spring Bean也有了进一步的认识。

回顾Bean创建的整体流程,发现Spring为我们提供了众多PostProcessor增强扩展点,以支持我们在Bean的生命周期过程中自定义修改,几乎遍布在每一个阶段,我们都可以进行Bean创建过程的干预,大大提高了Spring框架的灵活性和可扩展性。应用在我们工作的架构设计中,可以借鉴这些思路,将关注点分离、模块解耦,增强应用程序的可扩展性及可维护性。

如果觉得内容还不错,大家可以先点点关注,后续小豪也会更新Spring底层源码其它系列文章哦~

  • 26
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值