spring5.3 四:Bean的生命周期源码解析中

文章目录

  • Bean的生命周期源码解析中
    • Bean的生成过程
      • getBean方法如何创建bean
      • createBean方法创建bean
      • 加载类
      • 实例化前
      • 实例化
      • BeanDefinition的后置处理
      • 实例化后
      • 自动注入和处理属性
      • 执行Aware
      • 初始化前
      • 初始化
      • 初始化后

Bean的生命周期源码解析中

上一篇说了 bean的的创建需要生成BeanDefinition,合并BeanDefinition,然后通过getBean方法创建bean,那么现在就来看下getBean是如何创建bean的

Bean的生成过程

getBean方法如何创建bean

protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {
		//传进来的name有可能是&xxx或者xxx或者别名
		//下面这个方法通过do while 删除&符号同时或者对别名处理
		String beanName = transformedBeanName(name);
		Object beanInstance;
		//从单例池中获取bean  这里面涉及到循环依赖的处理
		Object sharedInstance = getSingleton(beanName);
		//这个if判断获取到的单例bean是不是是FactoryBean  如果是调用getObjectForBeanInstance方法
		if (sharedInstance != null && args == null) {
			if (logger.isTraceEnabled()) {
				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 + "'");
				}
			}
			//如果sharedInstance 是FactoryBean 则调用getObject方法返回对象
			beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}
		else {
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}
			//这个if大致过程就是先判断有没有父BeanFactory
			// 根据beanName获取BeanDefinition,如果没有就从parentBeanFactory就是父BeanFactory中获取
			//具体的做法就是调用父BeanFactory的getBean方法
			BeanFactory parentBeanFactory = getParentBeanFactory();
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
				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 if (requiredType != null) {
					// No args -> delegate to standard getBean method.
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
				else {
					return (T) parentBeanFactory.getBean(nameToLookup);
				}
			}
			if (!typeCheckOnly) {
				markBeanAsCreated(beanName);
			}
			StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
					.tag("beanName", name);
			try {
				if (requiredType != null) {
					beanCreation.tag("beanType", requiredType::toString);
				}
				//获取合并后的RootBeanDefinition  大致过程就是从Map中根据beanName获取RootBeanDefinition
				RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				//检查RootBeanDefinition是不是抽象的 是的话就会抛异常
				checkMergedBeanDefinition(mbd, beanName, args);
				//获取设置@DependsOn()的值
				String[] dependsOn = mbd.getDependsOn();
				//这个if主要解决@DependsOn()的作用
				// 如果A类上边有@DependsOn(B类的beanName)  那么就会先创建B类  创建不了B类就会抛异常
				if (dependsOn != null) {
					// dependsOn表示当前beanName所依赖的
					for (String dep : dependsOn) {
						// beanName是不是被dep依赖了,如果是则出现了循环依赖
						//就是说 A类依赖B类 如果B类也依赖A类  就出现循环依赖 抛异常
						if (isDependent(beanName, dep)) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
						}
						//这里涉及到两个Map 一个是dependentBeanMap 一个是 dependenciesForBeanMap
						// dependentBeanMap :某个bean被哪些bean依赖了
						// dependenciesForBeanMap :某个bean依赖了哪些bean
						// dep被beanName依赖了,存入dependentBeanMap中,dep为key,beanName为value
						registerDependentBean(dep, beanName);
						// 创建所依赖的bean
						try {
							getBean(dep);
						}
						catch (NoSuchBeanDefinitionException ex) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
						}
					}
				}
				//这个if else 主要根据主用域 也就是@Scope的值做出响应创建bean的方式
				//如果RootBeanDefinition是单例的
				if (mbd.isSingleton()) {
					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.
							destroySingleton(beanName);
							throw ex;
						}
					});
					//判断是不是FactoryBean对象如果是就会调用getObject方法
					beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}
				//如果RootBeanDefinition是原型的
				else if (mbd.isPrototype()) {
					// It's a prototype -> create a new instance.
					Object prototypeInstance = null;
					try {
						beforePrototypeCreation(beanName);
						//创建bean的方法
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						//删除创建bean的标记
						afterPrototypeCreation(beanName);
					}
					//判断是不是FactoryBean对象如果是就会调用getObject方法
					beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}
				//其他类型的作用域  例如springMVC 里面的  request session 等等
				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);
							}
						});
						beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					}
					catch (IllegalStateException ex) {
						throw new ScopeNotActiveException(beanName, scopeName, ex);
					}
				}
			}
			catch (BeansException ex) {
				beanCreation.tag("exception", ex.getClass().toString());
				beanCreation.tag("message", String.valueOf(ex.getMessage()));
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
			finally {
				beanCreation.end();
			}
		}

		// 检查通过name所获得到的beanInstance的类型是否是requiredType
		return adaptBeanInstance(name, beanInstance, requiredType);
	}

上述代码大致流程就是,首先根据传进来的name做处理获取到beanName,根据beanName从单例池中获取,如果获取到判断是不是FactoryBean,然后出对应处理。一般来说是获取不到的,执行else的代码。if (parentBeanFactory != null && !containsBeanDefinition(beanName)) 判断有没有父BeanFactory然后做对应处理。if (dependsOn != null) 处理dependsOn 注解。后续的if就是判断该bean是单例的还是原型还是springmvc相关内容的做出对应处理。
这部分代码都是一些判断,主要核心创建bean的代码是createBean方法

createBean方法创建bean

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {
		if (logger.isTraceEnabled()) {
			logger.trace("Creating instance of bean '" + beanName + "'");
		}
		RootBeanDefinition mbdToUse = mbd;
		// 马上就要实例化Bean了,确保beanClass被加载了 开始类加载的步骤
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			//给RootBeanDefinition赋值class对象  之前可能是类名(一个字符串)
			mbdToUse.setBeanClass(resolvedClass);
		}
		try {
			//和lookUp注解有关  暂时不管
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}
		try {
			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
			// 实例化前
			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 {
			//核心方法 这个方法 涉及 合并BeanDefinition的处理 实例化  实例化后  属性赋值  初始化前后等过程
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isTraceEnabled()) {
				logger.trace("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);
		}
	}

大致流程是,加载类,实例化前的处理,然后核心方法doCreateBean(beanName, mbdToUse, args)的处理,该方法包含了 实例化,实例化后,属性赋值,初始化前后等过程。下面对核心部分一一分析

加载类

这部分过程主要体现在createBean方法中的resolveBeanClass(mbd, beanName)
resolveBeanClass(mbd, beanName)的核心代码

// 如果beanClass被加载了
if (mbd.hasBeanClass()) {
 return mbd.getBeanClass();
}
// 如果beanClass没有被加载
if (System.getSecurityManager() != null) {
 return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>) () ->
  doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
 }
else {//这个方法开始加载类
 return doResolveBeanClass(mbd, typesToMatch);
}

public boolean hasBeanClass() {
 return (this.beanClass instanceof Class);
}

如果beanClass属性的类型是Class,那么就直接返回,如果不是,则会根据类名进行加载(doResolveBeanClass方法所做的事情)
会利用BeanFactory所设置的类加载器来加载类,如果没有设置,则默认使用ClassUtils.getDefaultClassLoader()所返回的类加载器来加载。
ClassUtils.getDefaultClassLoader()

  1. 优先返回当前线程中的ClassLoader
  2. 线程中类加载器为null的情况下,返回ClassUtils类的类加载器
  3. 如果ClassUtils类的类加载器为空,那么则表示是Bootstrap类加载器加载的ClassUtils类,那么则返回系统类加载器

实例化前

在Spring中,实例化对象之前,Spring提供了一个扩展点,允许用户来控制是否在某个或某些Bean实例化之前做一些启动动作。这部分过程主要体现在createBean方法中的resolveBeforeInstantiation(beanName, mbdToUse)

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			//hasInstantiationAwareBeanPostProcessors()判断有没有InstantiationAwareBeanPostProcessor的实现类
			//大致过程:从BeanPostProcessorCache中获取List判断是否为空 空就没有
			//而BeanPostProcessorCache是一个静态内部类 作用是分类缓存实现了BeanPostProcessor接口的接口,把他们分类放入到list中
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				//如果有InstantiationAwareBeanPostProcessor的实现类
				Class<?> targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
					//实例化前方法
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					//如果实例化前返回了bean那么就会直接调用初始化后方法
					if (bean != null) {
						//初始化后方法
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
		//遍历 List 调用实现类的postProcessBeforeInstantiation
		//如果其中一个实现类重写的postProcessBeforeInstantiation方法有返回值就直接return了  不会再走下一个实现了
		//如果没有返回值 就会循环调用每一个实现类重写的postProcessBeforeInstantiation方法
		for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
			Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
			if (result != null) {
				return result;
			}
		}
		return null;
}

实例化

这部分过程主要体现在doCreateBean方法中下面代码这部分

// 实例化bean
		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			// 有可能在本Bean创建之前,就有其他Bean把当前Bean给创建出来了(比如依赖注入过程中)
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			// 创建Bean实例 涉及到构造方法的推断  @bean注解的方法调用  工厂方法创建bean
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}

实例化核心代码在于createBeanInstance(beanName, mbd, args); createBeanInstance这部分代码涉及到构造方法的推断 @bean注解的方法调用 工厂方法创建bean等。后续会详细分析

BeanDefinition的后置处理

这部分过程主要体现在doCreateBean方法中下面代码这部分

synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					//从BeanPostProcessor的缓存类BeanPostProcessorCache获取List
					//遍历这个list 执行重写的方法
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				mbd.postProcessed = true;
			}
		}

protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
		for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {
			processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);
		}
	}

Bean对象实例化出来之后,接下来就应该给对象的属性赋值了。在真正给属性赋值之前,Spring又提供了一个扩展点MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(),可以对此时的BeanDefinition进行加工

实例化后

BeanDefinition的后置处理结束后会就到了doCreateBean方法中的populateBean(beanName, mbd, instanceWrapper);。这部分代码主要涉及属性填充。在这部分代码中同时包含了对实例化后的处理。
Spring又设计了一个扩展点:InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()

自动注入和处理属性

这部分核心都在于populateBean(beanName, mbd, instanceWrapper);方法中,该方法执行了实例化后的处理,就开始处理自动注入和属性依赖等等。这里也有一个扩展点,就是InstantiationAwareBeanPostProcessorpostProcessProperties。例如@Autowired @Resource等注解都是基于InstantiationAwareBeanPostProcessor的实现类来处理。这部分后续详细分析

执行Aware

在执行完populateBean(beanName, mbd, instanceWrapper); 方法后 就到了 初始化的部分,主要流程在initializeBean(beanName, exposedObject, mbd); 这部分代码中,会先执行Aware回调

	invokeAwareMethods(beanName, bean);
	private void invokeAwareMethods(String beanName, Object bean) {
		if (bean instanceof Aware) {
			if (bean instanceof BeanNameAware) {
				((BeanNameAware) bean).setBeanName(beanName);
			}
			if (bean instanceof BeanClassLoaderAware) {
				ClassLoader bcl = getBeanClassLoader();
				if (bcl != null) {
					((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
				}
			}
			if (bean instanceof BeanFactoryAware) {
				((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
			}
		}
	}

完成了属性赋值之后,Spring会执行一些回调,包括:

  • BeanNameAware:回传beanName给bean对象。
  • BeanClassLoaderAware:回传classLoader给bean对象。
  • BeanFactoryAware:回传beanFactory给对象

这也是spring的一个扩展点

初始化前

初始化前,也是Spring提供的一个扩展点:BeanPostProcessor.postProcessBeforeInitialization()。利用初始化前,可以对进行了依赖注入的Bean进行处理。

@Override
	public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessBeforeInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

Spring源码中:
InitDestroyAnnotationBeanPostProcessor会在初始化前这个步骤中执行@PostConstruct的方法,
ApplicationContextAwareProcessor会在初始化前这个步骤中进行其他Aware的回调:
EnvironmentAware:回传环境变量
EmbeddedValueResolverAware:回传占位符解析器
ResourceLoaderAware:回传资源加载器
ApplicationEventPublisherAware:回传事件发布器
MessageSourceAware:回传国际化资源
ApplicationStartupAware:回传应用其他监听对象,可忽略
ApplicationContextAware:回传Spring容器ApplicationContext

初始化

invokeInitMethods(beanName, wrappedBean, mbd);
//invokeInitMethods中部分代码
if (mbd != null && bean.getClass() != NullBean.class) {
			String initMethodName = mbd.getInitMethodName();
			if (StringUtils.hasLength(initMethodName) &&
					!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
					!mbd.isExternallyManagedInitMethod(initMethodName)) {
				invokeCustomInitMethod(beanName, bean, mbd);
			}
		}

查看当前Bean对象是否实现了InitializingBean接口,如果实现了就调用其afterPropertiesSet()方法
执行BeanDefinition中指定的初始化方法

初始化后

这是Bean创建生命周期中的最后一个步骤,也是Spring提供的一个扩展点:BeanPostProcessor.postProcessAfterInitialization()
可以在这个步骤中,对Bean最终进行处理,Spring中的AOP就是基于初始化后实现的,初始化后返回的对象才是最终的Bean对象。

你可能感兴趣的:(源码学习,spring)