spring中bean的生命周期总览

概述

spring在初始化时,容器会自动将创建去创建非懒加载的单例Bean,由于spring创建Bean的过程涉及到的步骤极其复杂,笔者本篇只是对创建Bean的流程进行概述,具体细节会在后续文章中给大家展示

Bean的实例化

public void preInstantiateSingletons() throws BeansException {
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
		for (String beanName : beanNames) {  // userService
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				if (isFactoryBean(beanName)) {
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						final FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						if (isEagerInit) {
							getBean(beanName);
						}
					}
				}
				else {
					// 根据beanName去创建bean
					getBean(beanName);
				}
			}
		}
		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();
				}
			}
		}
	}

重温以下方法的调用栈:
refresh() --> finishBeanFactoryInitialization(beanFactory) --> preInstantiateSingletons()
在preInstantiateSingletons() 这个方法里面最主要的就是这两个循环了

第一个循环首先是对spring扫描到的BeanDefinition进行循环,对每个循环的BeanDefinition所代表的类进行判断,判断对应的类是不是单例,是不是非抽象,是不是非懒加载的Bean,如果全部满足才会进行创建Bean的操作,有关于FactoryBean的创建已经在笔者《spring之BeanFactory源码解析》一文中进行了说明,这里就不再过多说明

我们直接进入spring创建Bean的方法doGetBean

Object sharedInstance = getSingleton(beanName);  // Map<>

首先依然是从单例池里面进行获取,如果获取到了就会直接返回

			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				String nameToLookup = originalBeanName(name);
				if (parentBeanFactory instanceof AbstractBeanFactory) {
					return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
							nameToLookup, requiredType, args, typeCheckOnly);
				}
				else if (args != null) {
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				else if (requiredType != null) {
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
				else {
					return (T) parentBeanFactory.getBean(nameToLookup);
				}
			}

如果说单例池里面没有这个Bean还会去父BeanFactory里面去寻找,如果说父BeanFactory里面也没有,那么就需要去创建 这个Bean了

		final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);
				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 {
							// 先去生成所依赖的bean
							getBean(dep); //  getBean("xxx")
						}
						catch (NoSuchBeanDefinitionException ex) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
						}
					}
				}

在这一段代码里面做了如下操作

  1. 合并BeanDefinition
    2)获取当前创建的Bean所依赖的Bean,也就是注解@DependsOn的Bean,在创建当前Bean之前,会先对这些所依赖的Bean进行创建

在这里有一个比较重要的判断是 isDependent(beanName, dep) ,就是去判断循环依赖关系举个例子:
假如类A dependOn 类B,同时类B dependOn 类A,那么就会产生循环依赖关系,基于dependOn这个属性产生的循环依赖关系是没有办法进行解决的 ,所以如果有这种情况就会直接抛出异常,这一部分的实现是基于两个map来实现的,一个map存储,这个Bean依赖哪些Bean,而另外一个map存储我当前的Bean被哪些bean所依赖,根据这两个map来完成判断

接下来看看一个单例bean到底是如何进行创建的,创建单例Bean依赖 getSingleton 这个方法

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		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!)");
				}
				beforeSingletonCreation(beanName);
				boolean newSingleton = false;
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<>();
				}
				try {
					singletonObject = singletonFactory.getObject();  // createBean()
					newSingleton = true;
				}
				....
				....
		}
	}

在这里最需要关注的是这个getObject()这个方法,singletonFactory是在方法内的第二个形参,传入的是一个表达式,这里调用的getObject其实就是执行表达式里面的createBean这个方法

	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {
		RootBeanDefinition mbdToUse = mbd;
		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) {.....}

		try {
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);  // 对象
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {...}

		try {
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			return beanInstance;
		}
		catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {....}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
		}
	}

即然要实例化一个类,拿前提条件当然是拿到这个类的class对象了,这里不免会产生一个疑问,class对象难道不是扫描的时候进行加载的么?
答案是:不是的,spring在进行扫描的时候并不是通过class对象来获取类上的信息,而是通过ASM技术直接读取字节码文件获取到类的信息,然后封装到BeanDefinition中的,所以到此位置是没有进行类的加载的

Object bean = resolveBeforeInstantiation(beanName, mbdToUse)
在这个方法里就是进行一些实例化之前的操作,在这里就涉及到spring中的后置处理器了

	@Nullable
	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				Class<?> targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					if (bean != null) {
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}

在这里回去spring容器里面找 InstantiationAwareBeanPostProcessor 这个处理器,如果有这个类型的处理器就会执行其postProcessBeforeInstantiation 这个方法,如果这个方法返回出来的对象不是null,那么还会执行一个实例化之后的一些操作,对应postProcessAfterInitialization这个方法,然后就会在这里直接进行返回这个Bean,从而不会有后续对这个Bean的实例化操作

通过这里的这个机制,如果有一天,我们不想让spring给我们创建对象,而是想通过自己进行对象的创建,那么我们既可以实现InstantiationAwareBeanPostProcessor 这个后置处理器,然后将自己创建对象进行返回

在进行spring实例化之前的一些操作过后,对应的就是Bean的实例化了,调用 doCreateBean(beanName, mbdToUse, args);进行bean的实例化

	protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		final Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {...}
				mbd.postProcessed = true;
			}
		}
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));  // AService
		}

		Object exposedObject = bean;
		try {
			populateBean(beanName, mbd, instanceWrapper);
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		catch (Throwable ex) {....}
		if (earlySingletonExposure) {
			Object earlySingletonReference = getSingleton(beanName, false);  // earlySingletonObjects
			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()) {...}
				}
			}
		}
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {...}
		return exposedObject;
	}

在这个实例化的方法里面可以看到applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
这里也是一次后置处理器的调用,spring在这通过后置处理器向程序员提供了一个可以对BeanDefinition操纵的机会,因为虽然Bean已经被实例化出来了,但是也仅仅是被实例化出来了而已,对于后面的属性填充,生命周期方法以及aop操作依然收到BeanDefinition的影响

结束上述,就会进行填充属性populateBean(beanName, mbd, instanceWrapper);

然后进入initializeBean(),在这里面还会进行 Aware接口的调用,初始化前,初始化,初始化后这四步操作

首先来看Aware接口的调用这里会分别对实现了BeanNameAware,BeanClassLoaderAware,BeanFactoryAware
这三个接口进行属性填充,然后分别调用set/getXXX方法,但是我们知道在Spring中不仅仅只有着三个XXXAware
那么其他的Aware接口会在哪里执行呢???(下文揭晓答案)

	private void invokeAwareMethods(final String beanName, final 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);
			}
		}
	}

而对于初始化前,初始化后这两步操作分别对应着一个后置处理器进行操作

	Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			// 4.2、初始化前
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			// 4.3、初始化
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		if (mbd == null || !mbd.isSynthetic()) {
			// 4.4、初始化后 AOP  ()
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

前面提出了一个问题,spring中其他的Aware接口是在哪里执行的呢?答案就在初始化前的操作里面

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;
	}

这里通过getBeanPostProcessors()方法获取spring中所有的后置处理器,然后执行其postProcessBeforeInitialization()方法
除了我们自己加入的BeanPostProcessor,其中有一个BeanPostProcessor 叫做ApplicationContextAwareProcessor
在这个BeanPostProcessor的postProcessBeforeInitialization方法如下

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
				bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
				bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
			return bean;
		}
		AccessControlContext acc = null;
		...
		if (acc != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareInterfaces(bean);
				return null;
			}, acc);
		}
		else {invokeAwareInterfaces(bean);}
		return bean;
	}

在这个方法里面会判断传入的Bean是不是实现了这些接口中的某一个接口,如果是实现了的话就会回调其相应Aware接口的set方法

对于初始化操作,则是去判断是否实现了InitializingBean 然后回调其中的afterPropertiesSet

protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
			throws Throwable {

		boolean isInitializingBean = (bean instanceof InitializingBean);
		if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
			if (logger.isTraceEnabled()) {
				logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
			}
	...

总结

关于spring中bean的生命周期贯穿着非常多的后置处理器,通过这些处理器完成对象的实例化,初始化,以及保证可扩展性
大体的流程如下
1)实例化前
2)实例化(其中包括构造方法的推断)
3)BeanDefinition的修改
4)属性填充
5)执行xxxAware
6)初始化前
7)初始化
8)初始化后

具体细节会在后续更新

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值