java的Spring的Bean实例化深入理解

本文深入探讨了Spring中Bean的实例化过程,包括InstantiationAwareBeanPostProcessors的作用、Bean对象的创建流程,涉及BeanDefinition、BeanPostProcessor、 Aware接口、@PostConstruct等关键概念。文章详细分析了Bean实例化各个阶段,如构造、属性注入、初始化方法的调用,揭示了Spring容器如何管理Bean的生命周期。
摘要由CSDN通过智能技术生成

Bean的生命周期:

InstantiationAwareBeanPostProcessors前后置处理方法,在Bean实例化之前被调用,允许返回一个实例来替代默认的实例化过程。如果返回非空实例,则Spring将跳过默认的实例化步骤-》若是返回非空直接返回-》若为空则执行doCreateBean-》首先创建实例-》进行属性注入-》调initializeBean-》首先判断是否实现了aware接口的方法进行相应的资源注入-》执行beanpostprocessor的前置方法-》进入invokeInitMethods判断是否实现了initializingbean,若有则执行afterPropertiesSet方法-》后面在执行自定义的初始化方法-》beanpostprocess的后置方法-》容器销毁时执行deposiable接口的销毁方法和自定义的销毁方法

前言

前两篇文章分析了Spring XML和注解的解析原理,并将其封装为BeanDefinition对象存放到IOC容器中,而这些只是refresh方法中的其中一个步骤——obtainFreshBeanFactory,接下来就将围绕着这些BeanDefinition对象进行一系列的处理,如BeanDefinitionRegistryPostProcessor对象方法的调用、BeanFactoryPostProcessor对象方法的调用以及Bean实例的创建都离不开这些BeanDefinition对象。下面就来看看Spring是如何处理这些对象的。

正文

环境准备

首先我们先回忆下refresh方法:

	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			//为容器初始化做准备
			prepareRefresh();
			
			// 解析xml和注解
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// 给BeanFacory设置属性值以及添加一些处理器,即准备Spring的上下文环境
			prepareBeanFactory(beanFactory);

			try {
				// 由子类实现对BeanFacoty的一些后置处理
				postProcessBeanFactory(beanFactory);


				/*
				* BeanDefinitionRegistryPostProcessor
				* BeanFactoryPostProcessor
				* 完成对这两个接口的调用
				* */
				invokeBeanFactoryPostProcessors(beanFactory);

				/*
				* 把实现了BeanPostProcessor接口的类实例化,并且加入到BeanFactory中
				* */
				registerBeanPostProcessors(beanFactory);

				/*
				* 国际化
				* */
				initMessageSource();

				//初始化事件管理类
				initApplicationEventMulticaster();

				//这个方法着重理解模板设计模式,因为在springboot中,这个方法是用来做内嵌tomcat启动的
				onRefresh();

				/*
				* 往事件管理类中注册事件类
				* */
				registerListeners();


				/*
				* 1、bean实例化过程
				* 2、依赖注入
				* 3、注解支持
				* 4、BeanPostProcessor的执行
				* 5、Aop的入口
				*
				* */
				finishBeanFactoryInitialization(beanFactory);

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

prepareBeanFactorypostProcessBeanFactory没什么复杂的,关注一下里面设置了哪些值,添加了哪些对象就行,这些东西在后面的流程中会起到作用。尤其是postProcessBeanFactory,这是一个模板方法,在其子类AbstractRefreshableWebApplicationContext中设置了两个重要的标识:

	protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// 主要看着里面
		beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
		beanFactory.ignoreDependencyInterface(ServletContextAware.class);
		beanFactory.ignoreDependencyInterface(ServletConfigAware.class);

		WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
		WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
	}

	public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
		Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
		// Remove from old position, if any
		this.beanPostProcessors.remove(beanPostProcessor);
		// Track whether it is instantiation/destruction aware
		if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
			this.hasInstantiationAwareBeanPostProcessors = true;
		}
		if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
			this.hasDestructionAwareBeanPostProcessors = true;
		}
		// Add to end of list
		this.beanPostProcessors.add(beanPostProcessor);
	}

分别将hasInstantiationAwareBeanPostProcessorshasDestructionAwareBeanPostProcessors属性都设置成了true,可以猜一下它们有什么作用。

两个重要的Processor

在将上下文环境设置完成后,就是通过invokeBeanFactoryPostProcessors方法完成对BeanDefinitionRegistry以及BeanFactory的后置处理器的处理和调用,也就是依次调用BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口的实现类。我们可以通过实现这两个接口在在BeanDefinition注册完成后,对象实例化之前对容器中的BeanDefinition进行动态的增删查改,比如Spring中@Configuration注解的解析就是在这个过程中实现的。我们先来了解一下Spring内置的Processor实现有哪些:在这里插入图片描述
整个体系需要有个大概的印象,其中重点关注ConfigurationClassPostProcessor类,该类就是完成对@Configuration、@Bean等注解的解析注册,这一块的源码这里暂时不分析。继续开始的流程,进入到invokeBeanFactoryPostProcessors方法:

	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		// getBeanFactoryPostProcessors方法一般是获取不到值的,除非我们手动调用addBeanFactoryPostProcessor方法添加进去,
		// 换言之我们可以通过注解@Component或是手动调用addBeanFactoryPostProcessor方法来注入BeanFactoryPostProcessors对象
		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

		省略......
	}

这里面 通过委托模式调用PostProcessorRegistrationDelegateinvokeBeanFactoryPostProcessors方法,并传入了BeanFactoryProcessors对象,但需要注意getBeanFactoryPostProcessors方法不是获取通过xml配置Component注解注册到容器中的Processor对象,而是获取通过调用AbstractApplicationContext.addBeanFactoryPostProcessor方法添加的类,换言之我们实现了Processor接口后可以不在类上添加@Component,直接调用addBeanFactoryPostProcessor方法即可,但需要注意,这种方式并没有对应的BeanDefinition类,添加的对象也不存在于IOC容器中。
继续进入invokeBeanFactoryPostProcessors方法:

	public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
		Set<String> processedBeans = new HashSet<>();

		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

			// 优先处理通过addBeanFactoryPostProcessor方法添加的BeanFactoryPostProcessor
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				// 优先处理BeanDefinitionRegistryPostProcessor对象
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				else {
					regularPostProcessors.add(postProcessor);
				}
			}

			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

			//获取实现了BeanDefinitionRegistryPostProcessor接口的所有类的BeanDefinition对象的beanName
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				//判断是否实现了排序接口 PriorityOrdered
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}

			//排序
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);

			//调用过程
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();

			// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {

				//判断是否是实现的Ordered接口
				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
  • 24
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值