Spring源码-AnnotationConfigApplicationContext容器的创建过程
Spring提供了多种IOC容器用来管理bean,其中最常见的就是AnnotationConfigApplicationContext
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
AnnotationConfigApplicationContext构造函数如下
首先调用父类构造函数初始化一个BeanFactory
//调用父类无参构造函数初始化一个DefaultListableBeanFactory
public GenericApplicationContext() {this.beanFactory = new DefaultListableBeanFactory();
}
this();
register(componentClasses);
refresh();
1.this();
//初始化一个bean读取器AnnotatedBeanDefinitionReader,读取被注解的bean
this.reader = new AnnotatedBeanDefinitionReader(this);
//初始化一个bean扫描器,作用不大,需要手动调用.scan方法,解析配置类的时候会单独再new一个
this.scanner = new ClassPathBeanDefinitionScanner(this);
2.register(componentClasses);
主要步骤如下
1.生成配置类的BeanDefinition
2.处理bean作用域,有@Scope解析@Scope,没有默认解析成单例
3.通过AnnotationConfigUtils工具类解析通用注解
4.将配置类的bean定义加入容器的beanDefinitionMap中
注册配置类,核心源码如下
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,@Nullable BeanDefinitionCustomizer[] customizers) {//将配置类信息转换成AnnotatedGenericBeanDefinition对象(继承BeanDefinition)AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {return;}abd.setInstanceSupplier(supplier);//设置bean作用域,如果有@Scope注解则解析,没有默认为singletonScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);abd.setScope(scopeMetadata.getScopeName());//生成配置类beanNameString beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));//解析通用注解,主要是Lazy,Primary,DependsOn,Role,Description五个注解AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);if (qualifiers != null) {for (Class<? extends Annotation> qualifier : qualifiers) {if (Primary.class == qualifier) {abd.setPrimary(true);}else if (Lazy.class == qualifier) {abd.setLazyInit(true);}else {abd.addQualifier(new AutowireCandidateQualifier(qualifier));}}}if (customizers != null) {for (BeanDefinitionCustomizer customizer : customizers) {customizer.customize(abd);}}//将beanName和bean定义信息分装成BeanDefinitionHolder对象BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);//将bean定义注册到容器的beanDefinitionMap中,映射关系为beanName和beanDefinitionBeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);}
3.refresh();
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);// Register bean processors that intercept bean creation.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) {if (logger.isWarnEnabled()) {logger.warn("Exception encountered during context initialization - " +"cancelling refresh attempt: " + ex);}// Destroy already created singletons to avoid dangling resources.destroyBeans();// Reset 'active' flag.cancelRefresh(ex);// Propagate exception to caller.throw ex;}finally {// Reset common introspection caches in Spring's core, since we// might not ever need metadata for singleton beans anymore...resetCommonCaches();}}}
Spring源码-AnnotationConfigApplicationContext容器的创建过程相关推荐
- Spring MVC 原理探秘 - 容器的创建过程
1.简介 在上一篇文章中,我向大家介绍了 Spring MVC 是如何处理 HTTP 请求的.Spring MVC 可对外提供服务时,说明其已经处于了就绪状态.再次之前,Spring MVC 需要进行 ...
- Spring源码分析系列——bean创建过程分析(三)——工厂方法创建bean
前言 spring创建bean的方式 测试代码准备 createBeanInstance()方法分析 instantiateUsingFactoryMethod()方法分析 总结 spring创建be ...
- Spring源码解析二之创建Bean(实例化)
上一节我们分析到了createBean,而真正创建Bean的过程在doCreateBean过程,我们可以发现Spring的编码风格,do才是真正的过程,不带do的通常是在做在准备过程,并且我们跳过了一 ...
- Spring源码分析4---IOC加载过程补充总结
原文出自:http://cmsblogs.com IOC 之 获取验证模型 DTD 与 XSD 的区别 DTD(Document Type Definition),即文档类型定义,为 XML 文件的验 ...
- netty 5 alph1源码分析(服务端创建过程)
研究了netty的服务端创建过程.至于netty的优势,可以参照网络其他文章.<Netty系列之Netty 服务端创建>是 李林锋撰写的netty源码分析的一篇好文,绝对是技术干货.但抛开 ...
- 【spring源码】基于factoryMethod创建bean对象
案例: 1.定义Student类: @Data public class Student {private String name;private Integer age;public Student ...
- 源码分析netty服务器创建过程vs java nio服务器创建
1.Java NIO服务端创建 首先,我们通过一个时序图来看下如何创建一个NIO服务端并启动监听,接收多个客户端的连接,进行消息的异步读写. 示例代码(参考文献[2]): import java.io ...
- Spring源码分析之Bean的创建过程详解
前文传送门: Spring源码分析之预启动流程 Spring源码分析之BeanFactory体系结构 Spring源码分析之BeanFactoryPostProcessor调用过程详解 本文内容: 在 ...
- 转 Spring源码剖析——核心IOC容器原理
Spring源码剖析--核心IOC容器原理 2016年08月05日 15:06:16 阅读数:8312 标签: spring 源码 ioc 编程 bean 更多 个人分类: Java https:// ...
最新文章
- Python 合并2个list
- 《设计模式解析(第2版)》
- Windows Server 2008 升级安装
- linux遍历文件夹下所有文件大小,Linux系统遍历文件夹 获取文件大小的操作(C语言实现)...
- python输入语句-python2 和 pyhton3 输入语句写法
- linux命令ping
- java改变this指向_$.on()方法和addEventListener改变this指向
- hdu 2064汉诺塔III 递推
- linux c之gdb常用断点调试总结
- linux 查看显卡信号_Ubuntu 16.04安装nvidia显卡驱动以及各种坑(包含解决方案)
- html5 css练习 定位布局
- cocos2d-iphone 区分ipad和iphone
- matlab中phi什么意思,球面座標matlab中Theta和Phi角的範圍?
- Top Down Operator Precedence - 自顶向下算符优先分析法
- C++ 无法打开包括文件“mysql.h“: No such file or directory
- c# oracle 中文列名,sql中中文列名
- html制作简历供人填写,求职简历制作个人定制代写
- 计算机组装与维护考试题a卷,计算机组装与维护考试题A卷.docx
- 红楼梦人物分析系统c语言,红楼梦人物分析.doc
- android 全屏广告,手机端全屏广告展示问题
热门文章
- Goroutine泄漏
- 数字图像处理--车牌识别
- windows 新加硬盘 部分文件读不到_电脑硬件检测识别不出硬盘怎么办?是什么原因导致硬件检测识别不了硬盘?...
- 亚马逊运营:拒绝爆款
- C# 常用加密方法收集 对称,非对称
- 已重置应用默认设置老是弹出 html,Win10系统总是提醒已重置应用默认设置怎么办?...
- 深度学习项目实战——Kaggle竞赛(Humpback Whale Identification)
- html5表格源码,HTML5表格制作源代码.doc
- 大物热力学基础笔记_1
- Easyexcel配置自定义列与自定义顺序导出下载Excel文件