Spring createBean过程中BeanPostProcessor的处理机会

       Spring IOC在实例化bean的过程中,BeanPostProcessor有机会在bean Instantiation前后、initialize前后进行处理,下面了解下分别做了什么。

BeanPostProcessor处理时序图

       这里只涉及BeanPostProcessor处理,其他过程忽略:


其中,红色步骤为BeanPostProcessor的相关处理。

相关源码分析

AbstractAutowireCapableBeanFactory.java

// 实例化前的BeanPostProcessor处理,这里有机会返回bean的代理对象
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
	Object bean = null;
	if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
		// Make sure bean class is actually resolved at this point.
		if (mbd.hasBeanClass() && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			bean = applyBeanPostProcessorsBeforeInstantiation(mbd.getBeanClass(), beanName);
			if (bean != null) {
				bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
			}
		}
		mbd.beforeInstantiationResolved = (bean != null);
	}
	return bean;
}

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName)
		throws BeansException {

	for (BeanPostProcessor bp : getBeanPostProcessors()) {
		if (bp instanceof InstantiationAwareBeanPostProcessor) {
			InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
			Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
			if (result != null) {
				return result;
			}
		}
	}
	return null;
}

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
		throws BeansException {

	Object result = existingBean;
	for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
		result = beanProcessor.postProcessAfterInitialization(result, beanName);
		if (result == null) {
			return result;
		}
	}
	return result;
}

AbstractAutowireCapableBeanFactory.java

// BeanPostProcessor有机会修改RootBeanDefinition mbd
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName)
		throws BeansException {

	try {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof MergedBeanDefinitionPostProcessor) {
				MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
				bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
			}
		}
	}
	catch (Exception ex) {
		throw new BeanCreationException(mbd.getResourceDescription(), beanName,
				"Post-processing failed of bean type [" + beanType + "] failed", ex);
	}
}

AbstractAutowireCapableBeanFactory.java

// BeanPostProcessor在bean初始化前的处理
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
		throws BeansException {

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

// bean的初始化
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
		throws Throwable {

	boolean isInitializingBean = (bean instanceof InitializingBean);
	if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
		if (logger.isDebugEnabled()) {
			logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
		}
		if (System.getSecurityManager() != null) {
			try {
				AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
					public Object run() throws Exception {
						((InitializingBean) bean).afterPropertiesSet();
						return null;
					}
				}, getAccessControlContext());
			}
			catch (PrivilegedActionException pae) {
				throw pae.getException();
			}
		}
		else {
			((InitializingBean) bean).afterPropertiesSet(); // bean的初始化
		}
	}

	if (mbd != null) {
		String initMethodName = mbd.getInitMethodName();
		if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
				!mbd.isExternallyManagedInitMethod(initMethodName)) {
			invokeCustomInitMethod(beanName, bean, mbd);
		}
	}
}

// BeanPostProcessor在bean初始化后的处理
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
		throws BeansException {

	Object result = existingBean;
	for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
		result = beanProcessor.postProcessAfterInitialization(result, beanName);
		if (result == null) {
			return result;
		}
	}
	return result;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring 启动过程是一个比较复杂的过程,主要包括以下几个步骤: 1. 加载 Spring 配置文件,创建 Bean 的定义信息。 2. 根据 Bean 的定义信息创建 Bean 实例,并进行依赖注入。 3. 将 Bean 实例注册到 Spring 容器。 4. 根据配置信息对 Bean 实例进行初始化。 5. 在 Spring 容器启动完成后,触发相关的回调方法。 其,涉及到的主要源码方法如下: 1. 加载 Spring 配置文件,创建 Bean 的定义信息: - `org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition`:注册 Bean 定义信息。 - `org.springframework.beans.factory.support.BeanDefinitionReaderUtils#registerBeanDefinition`:注册 Bean 定义信息的工具类方法。 2. 根据 Bean 的定义信息创建 Bean 实例,并进行依赖注入: - `org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean`:获取 Bean 实例的入口方法。 - `org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean`:创建 Bean 实例的方法。 - `org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean`:进行依赖注入的方法。 3. 将 Bean 实例注册到 Spring 容器: - `org.springframework.beans.factory.support.AbstractBeanFactory#registerSingleton`:注册单例 Bean 实例的方法。 - `org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingleton`:添加单例 Bean 实例的方法。 4. 根据配置信息对 Bean 实例进行初始化: - `org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean`:对 Bean 实例进行初始化的方法。 5. 在 Spring 容器启动完成后,触发相关的回调方法: - `org.springframework.context.support.AbstractApplicationContext#refresh`:刷新 Spring 容器,触发回调方法的入口方法。 - `org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors`:执行 BeanFactoryPostProcessor 的方法。 - `org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization`:完成 BeanFactory 初始化的方法。 - `org.springframework.context.support.AbstractApplicationContext#finishRefresh`:完成 Spring 容器的刷新,触发相关回调方法的方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值