前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring技术知识点总结之三——Spring Bean 的注入过程

Spring技术知识点总结之三——Spring Bean 的注入过程

作者头像
剑影啸清寒
发布2020-07-10 11:19:32
6050
发布2020-07-10 11:19:32
举报
文章被收录于专栏:琦小虾的Binary

接上篇《Spring技术知识点总结之二——SpringMVC DispatcherServlet》

三. Spring Bean 的注入过程

Spring ioc 容器的核心类是 AbstractApplicationContext,入口是 refresh() 方法,该方法是个模板方法,定义了加载到容器的全部过程。

代码语言:javascript
复制
@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			prepareRefresh();
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
			prepareBeanFactory(beanFactory);
			try {
				postProcessBeanFactory(beanFactory);
				// 注册 BeanDefinition 到 BeanDefinitionRegistry 中
				invokeBeanFactoryPostProcessors(beanFactory);
				registerBeanPostProcessors(beanFactory);
				initMessageSource();
				initApplicationEventMulticaster();
				onRefresh();
				registerListeners();
				// 将 BeanDefinition 转换为 Bean 实例
				finishBeanFactoryInitialization(beanFactory);
				finishRefresh();
			} catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}
				destroyBeans();
				cancelRefresh(ex);
				throw ex;
			}
			finally {
				resetCommonCaches();
			}
		}
	}

注入 Spring Bean 的逻辑主要在 refresh() 方法的两个方法中。

  1. invokeBeanFactoryPostProcessors:注册 BeanDefinition 到 BeanDefinitionRegistry 中;
  2. finishBeanFactoryInitialization:将 BeanDefinition 转换为 Bean 实例;

3.1 BeanDefinition 的注册

通常使用到的 BeanFactory 类是 DefaultListableBeanFactory,如下图的继承图所示,它实现了 BeanDefinitionRegistry 类,所以也实现了 BeanDefinitionRegistry#registerBeanDefinition() 方法,该方法将所有的 BeanDefinition 注册到 DefaultListableBeanFactory 中。

  1. 对于 XML 文件配置的 Bean,读取 bean 的 xml 配置文件,将 bean 元素分别转换成一个 BeanDefinition 对象;
  2. 对于注解类的 Bean 对象,AnnotationConfigApplicationContext 很关键,它是 spring 加载、管理 bean 的最重要的类。主要包括:
    • AnnotatedBeanDefinitionReader:用来加载 class 类型的配置信息,在它初始化的时候,会预先注册一些 BeanPostProcessor 和 BeanFactoryPostProcessor,为后续解析 Bean 和 Configuration 注解做准备;
    • ClasspathBeanDefinitionScanner:将指定包下的类通过一定规则过滤后,将 Class 信息包装成 BeanDefinition 的形式,注册到 IOC 容器中;
  3. 然后通过 BeanDefinitionRegistry 将这些 bean 注册到beanFactory中,保存在它的一个 ConcurrentHashMap 中。

注:将 BeanDefinition 注册到了 beanFactory 之后,在这里 Spring 为我们提供了一个扩展的切口,允许我们通过实现接口 BeanFactoryPostProcessor 来插入我们定义的代码。 典型的例子就是:PropertyPlaceholderConfigurer,我们一般在配置数据库的 dataSource 时使用到的占位符的值,就是它注入进去的。

3.2 BeanDefinition 到 Bean 的实例化

在后面的 finishBeanFactoryInitialization 中,调用了方法DefaultListableBeanFactory.preInstantiateSingletons(),该方法中会根据注册的 BeanDefinition 信息依此调用 getBean(beanName) ,将 bean 内容实例化。

注:实例化中可能出现循环依赖问题,见本篇《第一章》

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/07/09 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 三. Spring Bean 的注入过程
    • 3.1 BeanDefinition 的注册
      • 3.2 BeanDefinition 到 Bean 的实例化
      相关产品与服务
      容器服务
      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档