从getBean()分析BeanFactory和ApplicationContext

Posted 写Bug的渣渣高

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从getBean()分析BeanFactory和ApplicationContext相关的知识,希望对你有一定的参考价值。

本文说了哪些问题:

  • BeanFactory 是啥
  • ApplicationContext 是啥
  • 什么时候去实例化一个 bean, BeanFactory 和 ApplicationContext 实例化 bean 都是在什么时候

一个 Bean 什么时候被初始化

任何一个 Bean, 都是在 getBean () 的时候被初始化的.BeanFactory 需要字节手动调用 getbean 获取才会创建, 而 ApplicationContext 则是使用
那为什么还要区分 BeanFactory 呢?
这是因为 BeanFactory 初始化有这几个阶段

Resource resource = new ClassPathResource("applicationContext.xml");
// 创建一个DefaultListableBeanFactory
DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();
BeanDefinitionReader beanDefinitionReader = new 
// 创建XmlBeanDefinitonReder
XmlBeanDefinitionReader(defaultListableBeanFactory);
// loadBeanDefiniton
beanDefinitionReader.loadBeanDefinitions(resource);
本文不过多解释其他不重要的知识点, 着重于**文章题目**的解释

观点纠正:
注意了, loadBeanDefintions 方法并不会去实例化 Bean, 这里只是把我们定义的 Bean 的信息, 封装成 BeanDefiniton 而已, 并不会去实例化.

对于创建 Bean, 在 beanFactory 中, 则是以我们手动调用 getBean 为准, 才会去创建 Bean

很多时候, 我们使用 Spring 的时候, 并没有去手动的创建, bean 也都存在了啊??
这是什么情况.
这是因为 ApplicationContext 的预加载机制, 会加载所有的单例的非抽象的以及非懒加载的 Bean

看见懒加载, 那么懒加载的 bean 啥时候加载?? 还是 getBean.
然后你再猜猜预加载机制是通过什么方法来进行预加载的??
还是 getBean ()方法

先来看看 ClassPathXmlAplicationContext 的注释, ClassPathXmlApplicationContext 在容器初始化的时候, 就调用了父类的 refersh ()方法, 然后在其中的 finishBeanFactoryInitialization(beanFactory) 方法 ----> 调用了 beanFactory.preInstantiateSingletons(); 这一行关键代码

	public void preInstantiateSingletons() throws BeansException 
		if (logger.isTraceEnabled()) 
			logger.trace("Pre-instantiating singletons in " + this);
		

		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// 创建出所有的单实例Bean;Trigger initialization of all non-lazy singleton beans...
		for (String beanName : beanNames) 
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); //开始解析文件的时候每一个bean标签被解析封装成一个BeanDefinition
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) 
				if (isFactoryBean(beanName))  //如果是FactoryBean则执行下面逻辑
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); //得到HelloFactory
					if (bean instanceof FactoryBean) 
						FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) 
							isEagerInit = AccessController.doPrivileged(
									(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						
						else 
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						
						if (isEagerInit) 
							getBean(beanName);
						
					
				
				else  //不是FactoryBean则执行这个,普通的单实例非懒加载bean的创建
					getBean(beanName); //
				
			
		

		// 触发 post-initialization 逻辑;  Trigger post-initialization callback for all applicable beans...
		for (String beanName : beanNames) 
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) 
				StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
						.tag("beanName", beanName);
				SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) 
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> 
						smartSingleton.afterSingletonsInstantiated();
						return null;
					, getAccessControlContext());
				
				else 
					smartSingleton.afterSingletonsInstantiated();
				
				smartInitialize.end();
			
		
	
	public void preInstantiateSingletons() throws BeansException 
		if (logger.isTraceEnabled()) 
			logger.trace("Pre-instantiating singletons in " + this);
		
		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// 创建出所有的单实例Bean;Trigger initialization of all non-lazy singleton beans...
		for (String beanName : beanNames) 
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); //开始解析文件的时候每一个bean标签被解析封装成一个BeanDefinition
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) 
				if (isFactoryBean(beanName))  //如果是FactoryBean则执行下面逻辑
				// FACTORY_BEAN_PREFIX == '&'
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); //得到HelloFactory
					if (bean instanceof FactoryBean) 
						FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) 
							isEagerInit = AccessController.doPrivileged(
									(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						
						else 
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						
						if (isEagerInit) 
							getBean(beanName);
						
					
				
				else  //不是FactoryBean则执行这个,普通的单实例非懒加载bean的创建
					getBean(beanName); //
				
			
		

		// 触发 post-initialization 逻辑;  Trigger post-initialization callback for all applicable beans...
		for (String beanName : beanNames) 
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) 
				StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
						.tag("beanName", beanName);
				SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) 
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> 
						smartSingleton.afterSingletonsInstantiated();
						return null;
					, getAccessControlContext());
				
				else 
					smartSingleton.afterSingletonsInstantiated();
				
				smartInitialize.end();
			
		
	
	public void preInstantiateSingletons() throws BeansException 
		if (logger.isTraceEnabled()) 
			logger.trace("Pre-instantiating singletons in " + this);
		

		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// 创建出所有的单实例Bean;Trigger initialization of all non-lazy singleton beans...
		for (String beanName : beanNames) 
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); //开始解析文件的时候每一个bean标签被解析封装成一个BeanDefinition
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) 
				if (isFactoryBean(beanName))  //如果是FactoryBean则执行下面逻辑
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); //得到HelloFactory
					if (bean instanceof FactoryBean) 
						FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) 
							isEagerInit = AccessController.doPrivileged(
									(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						
						else 
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						
						if (isEagerInit) 
							getBean(beanName);
						
					
				
				else  //不是FactoryBean则执行这个,普通的单实例非懒加载bean的创建
					getBean(beanName); //
				
			
		

		// 触发 post-initialization 逻辑;  Trigger post-initialization callback for all applicable beans...
		for (String beanName : beanNames) 
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) 
				StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
						.tag("beanName", beanName);
				SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) 
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> 
						smartSingleton.afterSingletonsInstantiated();
						return null;
					, getAccessControlContext());
				
				else 
					smartSingleton.afterSingletonsInstantiated();
				
				smartInitialize.end();
			
		
	

注意, 这里是预加载, 预加载会加载所有的非懒加载的的单例的非抽象的 bean .而懒加载, 其实也是在 getBean ()的时候才会加载的.

延申

你有没有了解 BeanPostProcessor?
BeanPostProcessor 本质上也是 bean

参考一下 refresh () 的 registerBeanPostProcessors(beanFactory);

	protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) 
		PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
	
	public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) 

		// WARNING: Although it may appear that the body of this method can be easily
		// refactored to avoid the use of multiple loops and multiple lists, the use
		// of multiple lists and multiple passes over the names of processors is
		// intentional. We must ensure that we honor the contracts for PriorityOrdered
		// and Ordered processors. Specifically, we must NOT cause processors to be
		// instantiated (via getBean() invocations) or registered in the ApplicationContext
		// in the wrong order.
		//
		// Before submitting a pull request (PR) to change this method, please review the
		// list of all declined PRs involving changes to PostProcessorRegistrationDelegate
		// to ensure that your proposal does not result in a breaking change:
		// https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22
		//获取到容器中所有的 BeanPostProcessor; Bean的后置处理器
		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

		// Register BeanPostProcessorChecker that logs an info message when
		// a bean is created during BeanPostProcessor instantiation, i.e. when
		// a bean is not eligible for getting processed by all BeanPostProcessors.
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

		// Separate between BeanPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) 
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class))   //获取所有实现了 PriorityOrdered 的 BeanPostProcessor
				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
				priorityOrderedPostProcessors.add(pp);
				if (pp instanceof MergedBeanDefinitionPostProcessor) 
					internalPostProcessors.add(pp);
				
			
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) 
				orderedPostProcessorNames.add(ppName);
			
			else 
				nonOrderedPostProcessorNames.add(ppName);
			
		

		//首先,注册所有的实现了 PriorityOrdered 的 BeanPostProcessor ;  First, register the BeanPostProcessors that implement PriorityOrdered.
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		//接下来,注册所有的实现了 Ordered 的 BeanPostProcessor  Next, register the BeanPostProcessors that implement Ordered.
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String ppName : orderedPostProcessorNames) 
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); //获取后置处理器对象
			orderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) 
				internalPostProcessors.add(pp);
			
		
		sortPostProcessors(orderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		// 最后,注册所有普通的 BeanPostProcessor ;Now, register all regular BeanPostProcessors.
		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String ppName : nonOrderedPostProcessorNames) 
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); //从容器中获取这个组件
			nonOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) 
				internalPostProcessors.add(pp);
			
		
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

		//最后,重新注册所有internal的BeanPostProcessors  Finally, re-register all internal BeanPostProcessors.
		sortPostProcessors(internalPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

		// 重新注册一下这个后置处理器 Re-register post-processor for detecting inner beans as ApplicationListeners,
		// 把他放到后置处理器的最后一位; moving it to the end of the processor chain (for picking up proxies etc).
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	

以上是关于从getBean()分析BeanFactory和ApplicationContext的主要内容,如果未能解决你的问题,请参考以下文章

2.1.2_BeanFactory.getBean内部处理逻辑

spring源码分析——BeanFactory与FactoryBean的区别

Spring杂记BeanFactory之getBean方法

Spring源码解析 - BeanFactory

理解Spring中的getBean()

spring的beanFactory继承体系