Spring Bean的初始化和组装

我曾在<<spring 一览众山小>>一文中介绍了Spring是一个面向Bean的框架,整个框架的设计是基于Bean的,它的核心就是Bean。Bean其实就是一个Java对象,这个Java对象可能是非常简单的POJO,也可能这个对象会参与到Spring容器生命周期(实现了Spring指定的接口)。Spring 做为Bean的容器提供了Bean的定义、Bean初始化、Bean的组装等功能。本篇文章主要介绍Spring是如何完成Bean的初始化和组装的。

实际编程过程中我们通过Autowired就能实现自动依赖注入等,我们只需在我们的类或者方法上加上特定的注解就可以实现某些功能。这么神奇的事情Spring是如何帮我们做到的呢?本篇文章将为你揭开这神秘的面纱。

Bean的组装

说到Bean的初始化和组装就不得不提BeanPostProcessor,BeanPostProcessor 主要提供了对Bean的组装功能。Spring 提供了许多默认的BeanPostProcessor接口实现从而赋予了Spring依赖注入、事务、缓存等丰富强大的功能。我们也可以通过实现自己的BeanPostProcessor来丰富和完善特殊的功能。

BeanPostProcessor细分出来几个核心的子接口:

  • MergedBeanDefinitionPostProcessor 处理Bean的定义
  • InstantiationAwareBeanPostProcessor 初始化可以织入的Bean
  • DestructionAwareBeanPostProcessor 销毁Bean

InstantiationAwareBeanPostProcessor 和 DestructionAwareBeanPostProcessor在此文章中不做讲解,将在其他篇幅详细说明。

源码MergedBeanDefinitionPostProcessor:

public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor {

	/**
	 * Post-process the given merged bean definition for the specified bean.
	 * @param beanDefinition the merged bean definition for the bean
	 * @param beanType the actual type of the managed bean instance
	 * @param beanName the name of the bean
	 */
	void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);

}

源码BeanPostProcessor:

public interface BeanPostProcessor {
	
	Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;

	Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}

源码 AbstractAutowireCapableBeanFactory

@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args)throws BeanCreationException {
	if (logger.isDebugEnabled()) {
		logger.debug("Creating instance of bean '" + beanName + "'");
	}
	RootBeanDefinition mbdToUse = mbd;
	// Make sure bean class is actually resolved at this point, and
	// clone the bean definition in case of a dynamically resolved Class
	// which cannot be stored in the shared merged bean definition.
	Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
	if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
		mbdToUse = new RootBeanDefinition(mbd);
		mbdToUse.setBeanClass(resolvedClass);
	}
	// Prepare method overrides.
	try {
		mbdToUse.prepareMethodOverrides();
	}
	catch (BeanDefinitionValidationException ex) {
		....
	}
	try {
		// 调用 InstantiationAwareBeanPostProcessor
		Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
		if (bean != null) {
			return bean;
		}
	}
	catch (Throwable ex) {
		....
	}
	Object beanInstance = doCreateBean(beanName, mbdToUse, args);
	....

	return beanInstance;
}

// 创建一个Bean
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {

	...
	Object exposedObject = bean;
	try {
		// 实例化、设置对象属性
		populateBean(beanName, mbd, instanceWrapper);
		if (exposedObject != null) {
			// 调用MergedBeanDefinitionPostProcessor
			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);
		}
	}
	...

	// 初始化Bean
	protected Object initializeBean(final String beanName, final Object bean,RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged(new PrivilegedAction<Object>() {
				@Override
				public Object run() {
					invokeAwareMethods(beanName, bean);
					return null;
				}
			}, getAccessControlContext());
		}
		else {
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			// 调用初始化方法,afterPropertiesSetf方法或init-method方法
			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()) {
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}
		return wrappedBean;
	}
}

注:BeanPostProcessor的调用是在populateBean方法之后,populateBean方法用来实例化Bean和设置Bean的property。

BeanPostProcessor 接口主要定义了两个方法,postProcessBeforeInitialization方法在Bean初始化(afterPropertiesSetf方法或init-method方法)之前被调用。postProcessAfterInitialization方法在Bean初始化之后被调用。

BeanPostProcessor是多么的重要

源码AbstractApplicationContext

// 容器初始化或刷新时调用
public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		// Prepare this context for refreshing.
		prepareRefresh();

		// Tell the subclass to refresh the internal bean factory.
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		// Prepare the bean factory for use in this context.
		prepareBeanFactory(beanFactory);

		try {
			// Allows post-processing of the bean factory in context subclasses.
			postProcessBeanFactory(beanFactory);

			// Invoke factory processors registered as beans in the context.
			invokeBeanFactoryPostProcessors(beanFactory);

			// BeanPostProcessor的注册
			registerBeanPostProcessors(beanFactory);

			// Initialize message source for this context.
			initMessageSource();

			// Initialize event multicaster for this context.
			initApplicationEventMulticaster();

			// Initialize other special beans in specific context subclasses.
			onRefresh();

			// Check for listener beans and register them.
			registerListeners();

			// Instantiate all remaining (non-lazy-init) singletons.
			finishBeanFactoryInitialization(beanFactory);

			// Last step: publish corresponding event.
			finishRefresh();
		}

		catch (BeansException ex) {
			...
		}finally {
			...
		}
	}
}

注:BeanPostProcessor也是由Spring来管理的一种Bean,registerBeanPostProcessors方法在注册BeanPostProcessor时是通过beanFactory.getBeanNamesForType(…)方法或取BeanPostProcessor 的Bean 名称。getBeanNamesForType在获取Bean时如果Bean还没有被初始化则对Bean进行初始化,我们知道在Bean初始化时已注册的BeanPostProcessor会被调用。此时会出现BeanPostProcessor注册顺序的问题,如果一个BeanPostProcessor Bean在初始化之后,还未被注册的BeanPostProcessor是无法参与到这个Bean的初始化过程的。此时我们可以通过PriorityOrdered或Ordered接口来控制注册的顺序。

BeanPostProcessor的注册顺序

接下来我们梳理一下BeanPostProcessor的注册顺序,我们可以通过PriorityOrdered或Ordered接口来控制注册的顺序,那么没有实现PriorityOrdered或Ordered接口和实现了PriorityOrdered或Ordered接口的BeanPostProcessor顺序有时怎样的呢?

源码PostProcessorRegistrationDelegate:

public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

	String[] postProcessorNames = beanFactory.getBeanNamesForTyp(BeanPostProcessor.class, true, false);

	...

	// 1、注册实现了PriorityOrdered接口的
	sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
	registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

	// 2、注册实现了PriorityOrdered接口的
	sortPostProcessors(beanFactory, orderedPostProcessors);
	registerBeanPostProcessors(beanFactory, orderedPostProcessors);

	// Now, register all regular BeanPostProcessors.
	List<BeanPostProcessor> nonOrderedPostProcessors = newArrayList<BeanPostProcessor>();
	for (String ppName : nonOrderedPostProcessorNames) {
		BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
		nonOrderedPostProcessors.add(pp);
		if (pp instanceof MergedBeanDefinitionPostProcessor) {
			internalPostProcessors.add(pp);
		}
	}
	// 3、注册其他的
	registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

	// 4、注册实现了MergedBeanDefinitionPostProcessor接口的
	sortPostProcessors(beanFactory, internalPostProcessors);
	registerBeanPostProcessors(beanFactory, internalPostProcessors);

	beanFactory.addBeanPostProcessor(new ApplicationListenerDetecto(applicationContext));
}

BeanPostProcessor的注册顺序:

  • 实现了PriorityOrdered接口,默认从小到大排
  • 实现了Orderedj接口,默认从小到大排
  • 其他但没有实现MergedBeanDefinitionPostProcessor,按照获取到顺序
  • 实现了MergedBeanDefinitionPostProcessor接口,按照获取到顺序

到此我们已经了解BeanPostProcessor的作用和重要性了,接下来我们看一下Spring是如何通过BeanPostProcessor来实现Autowired注解的

Autowired原理

Autowired注解的支持是由AutowiredAnnotationBeanPostProcessor类实现的。

源码AutowiredAnnotationBeanPostProcessor:

public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter{
	....
}

AutowiredAnnotationBeanPostProcessor 实现了MergedBeanDefinitionPostProcessor接口,在检查到存在Autowired注解或Inject注解时,会修改Bean的定义。在之后Bean初始化时就自动注入了。

基于bert实现关系三元组抽取python源码+数据集+项目说明.zip基于bert实现关系三元组抽取python源码+数据集+项目说明.zip基于bert实现关系三元组抽取python源码+数据集+项目说明.zip基于bert实现关系三元组抽取python源码+数据集+项目说明.zip基于bert实现关系三元组抽取python源码+数据集+项目说明.zip 个人大四的毕业设计、课程设计、作业、经导师指导并认可通过的高分设计项目,评审平均分达96.5分。主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的学习者,也可作为课程设计、期末大作业。 [资源说明] 不懂运行,下载完可以私聊问,可远程教学 该资源内项目源码是个人的毕设或者课设、作业,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96.5分,放心下载使用! 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),供学习参考。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值