Spring-Bean实例化的生命周期

前言

Spring-Bean的实例化是发生在BeanFactorygetBean的方法中。其主要实现是在其子类AbstractBeanFactorydoGetBean方法中。
可以说,Spring中所有的对象都是通过这个方法实例化的。

doGetBean

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

		// 该方法作用:1、 如果是FactoryBean,会去掉Bean开头的&符号
		// 2、能存在传入别名且别名存在多重映射的情况,这里会返回最终的名字,如存在多层别名映射A->B->C->D,传入D,最终会返回A
		final String beanName = transformedBeanName(name);
		Object bean;
		//这里先尝试从缓存中获取,若获取不到,就走下面的创建
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			if (logger.isTraceEnabled()) {
				// 这里虽然只是一句日志,但是能说明用意。
				// 若条件为true,表示这个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 + "'");
				}
			}
			// 在getBean方法中,getObjectForBeanInstance是个频繁使用的方法。因此为了更好的知道细节,下面会详解这个方法的
			// 其实简单理解就是处理FactoryBean的getObject()方法
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {
			// 原型对象不允许循环创建,如果是原型对象正在创建,那就抛异常
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// 这一步也是必须要做的,若存在父容器,得看看父容器是否实例化过它了。避免被重复实例化(若父容器被实例化,就以父容器的为准)
			// 这就是为何,我们扫描controller,哪怕不加排除什么的,也不会出问题的原因~,因为Spring中的单例Bean只会被实例化一次(即使父子容器都扫描了)
			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);
			}

			try {
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);

				// 保证当前bean所依赖的bean的初始化。
				String[] dependsOn = mbd.getDependsOn();
				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 + "'");
						}
						registerDependentBean(dep, beanName);
						try {
							getBean(dep);
						}
						catch (NoSuchBeanDefinitionException ex) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
						}
					}
				}

				// 从这里开始,就正式开始着手创建这个Bean的实例了~~~~
				if (mbd.isSingleton()) {
					// 也是一样先尝试从缓存去获取,获取失败就通过ObjectFactory的createBean方法创建
					// 这个getSingleton方法和上面是重载方法,它支持通过ObjectFactory去根据Scope来创建对象,具体源码解析见下面
					sharedInstance = getSingleton(beanName, () -> {
						try {
							// 这是创建Bean的核心方法,非常重要~~~~~~~~~~~~~~~下面会有
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							// 执行失败,就销毁Bean。然后执行对应的destroy方法,等等销毁Bean时候的生命周期方法们
							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

				else if (mbd.isPrototype()) {
					// It's a prototype -> create a new instance.
					Object prototypeInstance = null;
					try {
						beforePrototypeCreation(beanName);
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						afterPrototypeCreation(beanName);
					}
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}

				else {
					String scopeName = mbd.getScope();
					final 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;
			}
		}

		//。。。。。。。。
	}

过程:
1、如果springBean名字以&符号开头,那么spring会将其去掉
2、判断当前单例bean是否在当前容器的单例池中。
3、如果不存在,在判断其父容器是否实例化过它了。避免被重复实例化(若父容器被实例化,就以父容器的为准)
3、如果其父容器没有实例化过它,先判断其是否是单例或者是原型对象。在调用相应的createBean方法创建bean对象

初始化单个单例bean的核心步骤

AbstractAutowireCapableBeanFactory的createBean

@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args){
		//.......
		try {
			// 容器里所有的InstantiationAwareBeanPostProcessors实例,都会在此处生效,进行前置处理~~~~~~~~~~
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		//.......
		try {
		    //执行bean的后置处理器和初始化方法
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isTraceEnabled()) {
				logger.trace("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
		//.......
	}
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		// 然后,唯一能改变它的值的地方,是下面这仅仅一行代码而已,它的访问权限为package
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			// 这里hasInstantiationAwareBeanPostProcessors()方法就是看属性hasInstantiationAwareBeanPostProcessors的值。就是标记容器里是否有InstantiationAwareBeanPostProcessor的实现
			// 显然,在执行addBeanPostProcessor,发现这个Bean是这个子类型的时候,就会设为true了。同理的还有hasDestructionAwareBeanPostProcessors这个属性,表示销毁的处理器
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				// 拿到最终的目标类型(放置被别的包装过)显然此处是;com.fsx.service.HelloServiceImpl
				// 可能依赖于AbstractBeanFactory#resolveBeanClass这个方法去解析
				Class<?> targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
					// 先执行执行InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation回调方法
					// 里面的逻辑也比较简单:拿到缓存好的(List装着的)所有的BeanPostProcessors,如果是InstantiationAwareBeanPostProcessor就执行吧~~
					// 只要有一个result不为null;后面的所有 后置处理器的方法就不执行了,直接返回(所以执行顺序很重要)
					//1、ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor这个内部类就是这个类型。主要还是去增强、完善处理@Configuration这种类   但是它并没有重写postProcessBeforeInstantiation这个方法,所以默认是返回null的
					//2、CommonAnnotationBeanPostProcessor/Autowired。。。也没做处理(若你自己不去注册,那系统里就再没有了)
					// 需要注意的是,如果我们采用了AOP、声明式事务等等,这里就会有了,后面又会回来讲解这一块
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					// 我们可以看到,如果bean为null,那就直接返回了  短路掉后面的After也就不执行了
					if (bean != null) {
						// 注意,这里是Initialization,是初始化的后置方法,是BeanPostProcessor的方法,也就是说初始化完成后的方法。
						// 为何这里执行这个方法呢?是因为我们上面说了,如果返回不为null,后面都都会被短路掉。但是此处Spring还是让我们执行了初始化后的处理器方法,这点需要引起注意
						// 就是说:即使Bean在实例化前已经返回了一个不为null的对象,别的方法都被短路了,但是我的【初始化】后处理器方法applyBeanPostProcessorsAfterInitializationh还是可以执行的
						// 这里面可以关注一下这个类:ApplicationListenerDetector
						//初始化之后的方法返回了null,那就需要调用doCreateBean生成对象了==============
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}

过程:
1、先执行InstantiationAwareBeanPostProcessor的applyBeanPostProcessorsBeforeInstantiation方法
2、如果applyBeanPostProcessorsBeforeInstantiation方法返会值不为null,就执行其applyBeanPostProcessorsAfterInitialization方法。
注意:一般情况下,这个方法返回值一定是null,除非我们要进行代理

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

		// 用BeanWrapper来持有创建出来的Bean对象
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			//如果是单例的话,则先把缓存中的同名bean清除(同名的)
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		//实际创建的交给createBeanInstance来完成,
		//bean的生成,这里会使用默认的类生成器,包装成BeanWrapperImpl类,为了下面的populateBean方法的属性注入做准备
		if (instanceWrapper == null) {
		     //调用构造器
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		final Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		//如果不是NullBean,则将resolvedTargetType 属性设置为当前的WrappedClass
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}

		// Allow post-processors to modify the merged bean definition.
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					// 此处处理这个接口的处理器:MergedBeanDefinitionPostProcessor,他在BeanPostProcessor的基础上增加了postProcessMergedBeanDefinition方法,在此处就被调用了
					// 主要是处理@PostConstruct,@Autowire,@Value,@Resource,@PreDestory等这些注解。(显然对应哪去处理器,一目了然了)
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				mbd.postProcessed = true;
			}
		}

		//如果当前bean是单例,且支持循环依赖,且当前bean正在创建,通过往singletonFactories添加一个objectFactory,这样后期如果有其他bean依赖该bean 可以从singletonFactories获取到bean
		//getEarlyBeanReference可以对返回的bean进行修改,这边目前除了可能会返回动态代理对象 其他的都是直接返回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");
			}
			// 这里面主要是解决循环引用问题~~~~~~~~~借助了这个工厂
			//这里主要是调用处理器:SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference方法去寻找到前期的Bean们(若存在这种处理器的话)
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// 这个Obj,就是最终要返回的对象了
		Object exposedObject = bean;
		try {
			// 这又是非常非常重要的一步:给已经初始化的属性们赋值===================对bean进行填充,在这里面完成依赖注入的相关内容
			// 啥都不说了,看下面的详解吧
			populateBean(beanName, mbd, instanceWrapper);
			//完成属性依赖注入后,进一步初始化Bean  具体进行了以下操作:
			//若实现了BeanNameAware, BeanClassLoaderAware,BeanFactoryAwareAware等接口,则注入相关对象
			//遍历后置处理器,调用实现的postProcessBeforeInitialization方法,
			//如果实现了initialzingBean,调用实现的 afterPropertiesSet()
			//如果配置了init-mothod,调用相应的init方法
			//遍历后置处理器,调用实现的postProcessAfterInitialization

			// 关于populateBean和initializeBean的详解,下贴出了博文链接参考~~~~~~
			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);
			}
		}
		//如果earlySingletonExposure为true,尝试从缓存获取该bean(一般存放在singletonFactories对象通过调用getObject 把对象存入earlySingletonObjects),
		// 分别从singletonObjects和earlySingletonObjects获取对象   这里依然是处理循环依赖相关问题的

		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 " +
								"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
					}
				}
			}
		}

		// 如果有需要,就注册DisposableBean,这样Bean销毁的时候此种后置处理器也会生效了
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		return exposedObject;
	}

Spring-Bean实例化生命周期宏观说明

注意:此处的Spring-Bean指的是我们自己创建的非后置器的单例Spring-Bean对象。

1、执行InstantiationAwareBeanPostProcessorpostProcessBeforeInstantiation(Class<?> beanClass, String beanName)方法 (其返回值为空)
2、执行Bean的构造器
3、执行MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition方法
4、执行InstantiationAwareBeanPostProcessorpostProcessAfterInitialization方法
5、执行InstantiationAwareBeanPostProcessorpostProcessProperties方法
6、执行InstantiationAwareBeanPostProcessorpostProcessPropertyValues方法
7:执行BeanNameAwaresetBeanName方法
8:执行BeanClassLoaderAwaresetBeanClassLoader方法
9:执行BeanFactoryAwaresetBeanFactory方法
10: 执行后置处理器BeanPostProcessorpostProcessBeforeInitialization(Object bean, String beanName)方法
11: 调用InitializingBean接口初始化 (如果配置了method-init,则调用其方法初始化 )
12: 执行后置处理器BeanPostProcessorpostProcessAfterInitialization方法

补充说明:在步骤1中如果 如果其返回值不是空,就会执行其postProcessAfterInitialization方法,如果postProcessAfterInitialization返回还不为null,那么下面的步骤就不会调用

完成此上下文bean工厂的初始化

AbstractApplicationContext

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		//初始化此上下文的转换服务。
		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,以便尽早注册其转换器。
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		//停止使用临时类加载器进行类型匹配。
		beanFactory.setTempClassLoader(null);

		//允许缓存所有bean定义元数据,不需要进一步更改。
		beanFactory.freezeConfiguration();

		//实例化所有剩余的(非延迟初始化)单例。
		beanFactory.preInstantiateSingletons();
	}

初始化所有剩余的单例bean

DefaultListableBeanFactory的preInstantiateSingletons

public void preInstantiateSingletons() throws BeansException {
		if (logger.isTraceEnabled()) {
			logger.trace("Pre-instantiating singletons in " + this);
		}
		//获取所有springbean的名字
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// 所有非惰性单例bean的触发器初始化。。。
		for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
			   //如果是FactoryBean方式创建的bean,进入这里
				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);
				}
			}
		}

		//为所有适用的bean触发初始化后回调。。。
		for (String beanName : beanNames) {
		    //注意回调只针对单利对象
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	}

过程:
1、获取所有springBean的名字
2、实例化所有非惰性单例bean,底层主要方法是getBean(beanName),而getBean底层又是doGetBean()方法
3、当所有非惰性单例bean实例化后,触发回调接口SmartInitializingSingletonafterSingletonsInstantiated方法。

SmartInitializingSingleton的作用:因为其方法afterSingletonsInstantiated是所有非惰性单例bean实例化后调用的,所有我们可以利用他获取所有的非惰性单例bean对象

@Component
public class MySmartInitializingSingleton implements SmartInitializingSingleton {
	@Autowired
	private DefaultListableBeanFactory defaultListableBeanFactory;
	@Override
	public void afterSingletonsInstantiated() {
		System.out.println("OK.........");
		Iterator<String> beanNamesIterator = defaultListableBeanFactory.getBeanNamesIterator();
		while (beanNamesIterator.hasNext()){
			System.out.println(beanNamesIterator.next());
		}
	}
}

SmartInitializingSingleton对象的创建时机和普通的非惰性单例bean一样

发布了34 篇原创文章 · 获赞 0 · 访问量 1372

猜你喜欢

转载自blog.csdn.net/qq_41071876/article/details/104395769