Spring的bean生命周期

一、bean的生命周期

1.1 代码示例

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

	@Override
	public void postProcessBeanFactory(
			ConfigurableListableBeanFactory beanFactory) throws BeansException {
		System.out.println("execute BeanFactoryPostProcessor#postProcessBeanFactory");
	}
}


public class MyBeanPostProcessor implements BeanPostProcessor {

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		System.out.println("execute BeanPostProcessor#postProcessBeforeInitialization for:"+beanName);
		return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		System.out.println("execute BeanPostProcessor#postProcessAfterInitialization for:"+beanName);
		return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
	}

}


public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

	@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName)
			throws BeansException {
		System.out.println(
				"execute InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation for:"
						+ beanName);
		return InstantiationAwareBeanPostProcessor.super
				.postProcessBeforeInstantiation(beanClass, beanName);
	}

	@Override
	public boolean postProcessAfterInstantiation(Object bean, String beanName)
			throws BeansException {
		System.out.println(
				"execute InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation for:"
						+ beanName);
		return InstantiationAwareBeanPostProcessor.super
				.postProcessAfterInstantiation(bean, beanName);
	}

	@Override
	public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
			throws BeansException {
		System.out.println("execute InstantiationAwareBeanPostProcessor#postProcessProperties for:"
				+ beanName);
		return InstantiationAwareBeanPostProcessor.super.postProcessProperties(pvs, bean, beanName);
	}

}


public class User implements BeanFactoryAware, BeanNameAware, ApplicationContextAware,
		InitializingBean, DisposableBean {

	/**
	 * user's name.
	 */
	private String name;

	/**
	 * user's age.
	 */
	private int age;

	/**
	 * bean factory.
	 */
	private BeanFactory beanFactory;

	/**
	 * application context.
	 */
	private ApplicationContext applicationContext;

	/**
	 * bean name.
	 */
	private String beanName;

	public User() {
		System.out.println("execute User#new User()");
	}

	public void setName(String name) {
		System.out.println("execute User#setName——" + name);
		this.name = name;
	}

	public void setAge(int age) {
		System.out.println("execute User#setAge——" + age);
		this.age = age;
	}

	@Override
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		System.out.println("execute BeanFactoryAware#setBeanFactory");
		this.beanFactory = beanFactory;
	}

	@Override
	public void setBeanName(String s) {
		System.out.println("execute BeanNameAware#setBeanName");
		this.beanName = s;
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		System.out.println("execute ApplicationContextAware#setApplicationContext");
		this.applicationContext = applicationContext;
	}

	@Override
	public void destroy() throws Exception {
		System.out.println("execute DisposableBean#destroy");
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		System.out.println("execute InitializingBean#afterPropertiesSet");
	}


	public void doInit() {
		System.out.println("execute User#doInit");
	}

	public void doDestroy() {
		System.out.println("execute User#doDestroy");
	}
}
<bean id="user" class="com.xyx.life.User" init-method="doInit" destroy-method="doDestroy">
		<property name="name" value="hzq"/>
	</bean>
	<bean id="myBeanFactoryPostProcessor" class="com.xyx.life.MyBeanFactoryPostProcessor"/>
	<bean id="myBeanPostProcessor" class="com.xyx.life.MyBeanPostProcessor"/>
	<bean id="myInstantiationAwareBeanPostProcessor" class="com.xyx.life.MyInstantiationAwareBeanPostProcessor"/>

1.2 总体步骤

(1)BeanFactoryPostProcessor

  1. BeanFactoryPostProcessor可以在实例化bean之前对bean元数据进行修改
  2. 可以实现多个BeanFactoryPostProcessor,通过设置“order”属性来控制BeanFactoryPostProcessor的执行次序
  3. BeanFactoryPostProcessor的作用域范围是容器级的。它只和你所使用的容器有关。如果你在容器中定义一个BeanFactoryPostProcessor,它仅仅对此容器中的bean进行后置处理。BeanFactoryPostProcessor不会对定义在另一个容器中的bean进行后置处理,即使这两个容器都是在同一层次上

(2)InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()

(3)调用 Bean 构造方法实例化 Bean

(4)InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()

(5)InstantiationAwareBeanPostProcessor.postProcessProperties()

(6)利用依赖注入完成 Bean 中所有属性值的配置注入(setXxx)

(7)BeanNameAware.setBeanName

(8)BeanFactoryAware.setBeanFactory

(9)ApplicationContextAware.setApplicationContext

(10)BeanPostProcessor.postProcessBeforeInitialization

(11)InitializingBean.afterPropertiesSet

(12)自定义Init方法

(12)BeanPostProcessor.postProcessAfterInitialization

(13)DisposableBean.destroy

(14)自定义destroy方法

1.3 源码分析

BeanFactoryPostProcessor在AbstractApplicationContext.invokeBeanFactoryPostProcessors会调用所有的BeanFactoryPostProcessor

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

		// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
		// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
		if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
	}

注册BeanPostProcessor,为后面实例化bean调用后置处理器做准备

private static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {

		if (beanFactory instanceof AbstractBeanFactory) {
			// Bulk addition is more efficient against our CopyOnWriteArrayList there
			((AbstractBeanFactory) beanFactory).addBeanPostProcessors(postProcessors);
		}
		else {
			for (BeanPostProcessor postProcessor : postProcessors) {
				beanFactory.addBeanPostProcessor(postProcessor);
			}
		}
	}

在创建AbstractAutowireCapableBeanFactory.createBean中,在调用doCreateBean之前,会调用InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation方法

@Override
	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;

		//锁定class,根据设置的class属性或者根据className来解析Class
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		// Prepare method overrides.
		try {
			//在Spring配置中是存在lookup-method和replace-method的,
			// 而这两个配置的加载其实就是将配置统一存放在BeanDefinition中的methodOverrides属性里
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
			// 应用初始化前的后处理器,解析指定bean是否存在初始化前的短路操作。
			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 {
			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);
		}
	}

createBean主要完成的功能:

  1. 根据设置的class属性或者根据className来解析Class。
  2. 对override属性进行标记及验证,这个主要是Spring配置中是存在lookup-method和replace-method的,而这两个配置的加载其实就是将配置统一存放在BeanDefinition中的methodOverrides属性里
  3. 应用初始化前的后处理器,解析指定bean是否存在初始化前的短路操作,调用InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
  4. 创建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) {
			//根据指定bean使用对应的策略创建新的实例,如:工厂方法、构造函数自动注入、简单初始化
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}

		// Allow post-processors to modify the merged bean definition.
		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;
			}
		}

		// 是否需要提早曝光:单例&允许循环依赖&当前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");
			}
			//避免后期循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂
			//AOP就是在这里将advice动态织入bean中
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			//对bean进行填充,将各个属性值注入
			populateBean(beanName, mbd, instanceWrapper);
			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 {
			//如果配置了destroy-method,这里需要注册以便于在销毁时候调用
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		return exposedObject;
	}

doCreateBean的主要功能:

  1. 如果是单例则需要首先清除缓存
  2. 根据指定bean使用对应的策略创建新的实例,如:工厂方法、构造函数自动注入、简单初始化
  3. 循环依赖检查与处理
  4. 调用populateBean完成属性填充,在调用set方法之前会调用InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation和postProcessProperties
  5. 完成属性填充,会调用initializeBean来初始化bean,初始化过程会调用Aware接口、后置处理器的前置方法、InitializingBean.afterPropertiesSet、自定义init以及后置处理器的后置方法
  6. 注册DisposableBean。如果配置了destroy-method,这里需要注册以便于在销毁时候调用

至于销毁方法的调用,ConfigurableApplicationContext调用registerShutdownHook会执行相应的销毁方法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值