Spring5源码分析之AnnotationConfigApplicationContext
前言: 主要了解的内容有如下几点:
- @Qualifier与@Primary注解的使用
- Spring中ApplicationContext的作用
- BeanFactory与ApplicationContext区别
- AnnotationConfigApplicationContext启动原理分析
假设 IUser两个实现类UserImpl1 和 UserImpl2
1. @Autowired + @Qualifier("UserImpl1") 可以指定使用哪个实现类。 也可以 @Resource("UserImpl1 ")
2. @Primary是指定加载谁,用在实现类上。指定。
图解:
ApplicationContext:也就是上下文
1. AnnotationConfigApplicationContext
2. ClassPathXmlApplicationContext
ApplicationContext 继承BeanFactory 实现扩展功能
小结:
@Configuration 相当于XML配置
注解方式启动,需要配置config,通过构造函数去加载config的配置信息

看下这个构造函数:

注意先执行父类的无参构造函数 再执行 子类的无参构造函数,无参构造函数如下:

有父类的: 多态! 先执行父类的无参构造!

父类的无参构造函数:

可以看出:创建了个beanFactory
然后走子类的无参构造函数:

第一个: 基于 注解方式
第二个: xml扫包方式

1走完了,继续2:

看下reader:

比如我们可以直接使用:

接着看2 : register()

继续看 register:
进行for循环遍历,多个注解情况

继续查看

查看该方法:注解情况的核心代码
public void registerBean(Class<?> annotatedClass, String name, Class... qualifiers) {
// 基于注解的类: 作用是
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
if (!this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
String beanName = name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry);
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
if (qualifiers != null) {
Class[] var7 = qualifiers;
int var8 = qualifiers.length;
for(int var9 = 0; var9 < var8; ++var9) {
Class<? extends Annotation> qualifier = var7[var9];
if (Primary.class == qualifier) {
abd.setPrimary(true);
} else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
} else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
}
传统的用: RootBeanDefinition 传统表示注入Bean对象
用注解的形式的话: AnnotatedGenericBeanDefinition

也是继承到了 BeanDefinition
也可以推理出 AnnotatedGenericBeanDefinition 表示为封装注解方式启动注入配置类。 注解方式启动的配置注入IOC Bean信息

根据条件注入Bean,Condition条件注入
设置回调

判断启动类上是否有Scope作用域,默认是单例的。设置作用域scope

beanName的默认和设置,没有就生成一个
调用了工具类

工具类要做的是: 读取配置类上面的 注解信息 比如有没有加上 @DependsOn 加载顺序 @Role 角色分类 @Primary 等

最终会在:registerBean方法中new
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);

通过AnnotatedGenericBeanDefinition 封装注解的启动类
DefinitionHolder 包装了 这个类: AnnotatedGenericBeanDefinition
然后通过工具类进行注册:

然后进行注册:

画图整理:

Spring5源码分析之AnnotationConfigApplicationContext的更多相关文章
- Spring5源码分析(1)设计思想与结构
1 源码地址(带有中文注解)git@github.com:yakax/spring-framework-5.0.2.RELEASE--.git Spring 的设计初衷其实就是为了简化我们的开发 基于 ...
- Spring5源码分析之Bean生命周期
Spring Bean生命周期的构成 Bean的完整生命周期经历了各种方法调用,这些方法可以划分为以下几类: Bean自身的方法: 这个包括了Bean本身调用的方法和通过配置文件中<bean&g ...
- Spring5源码分析之启动类的相关接口和注解
一些基础但是核心的知识总结: Spring Boot项目启动的时候需要加@Configuration. @ComponentScan @Configuration + @Bean 把第三方jar包注入 ...
- spring5源码分析系列(三)——IOC容器的初始化(一)
前言: IOC容器的初始化包括BeanDefinition的Resource定位.载入.注册三个基本过程. 本文以ApplicationContext为例讲解,XmlWebApplicationCon ...
- spring5源码分析系列(二)——spring核心容器体系结构
首先我们来认识下IOC和DI: IOC(Inversion of Control)控制反转:控制反转,就是把原先代码里面需要实现的对象创建.依赖的代码,反转给容器来帮忙实现.所以需要创建一个容器,并且 ...
- spring5源码分析系列(一)——spring5框架模块
spring总共大约20个模块,这些模块被整合在核心容器(Core Container).AOP和设备支持.数据访问及集成.Web.报文发送.Test 6个模块集合. 组成Spring框架的每个模块集 ...
- Spring5深度源码分析(三)之AnnotationConfigApplicationContext启动原理分析
代码地址:https://github.com/showkawa/spring-annotation/tree/master/src/main/java/com/brian AnnotationCon ...
- 5.2 Spring5源码--Spring AOP源码分析二
目标: 1. 什么是AOP, 什么是AspectJ 2. 什么是Spring AOP 3. Spring AOP注解版实现原理 4. Spring AOP切面原理解析 一. 认识AOP及其使用 详见博 ...
- 5.2 spring5源码--spring AOP源码分析二--切面的配置方式
目标: 1. 什么是AOP, 什么是AspectJ 2. 什么是Spring AOP 3. Spring AOP注解版实现原理 4. Spring AOP切面原理解析 一. 认识AOP及其使用 详见博 ...
随机推荐
- 【转】以Python为例的Async / Await的编程基础
转, 原文:https://www.cnblogs.com/middleware/p/11996731.html 以Python为例的Async / Await的编程基础 -------------- ...
- java在win系统下的环境的搭建
学习Java第一步是配置本地开发环境,学习最基本的桌面开发,下面以win7为例配置Java开发环境,安装JDK的时候会默认安装JRE,根据提示安装就可以了. 首先去官网下载适合系统版本的JDK,下载地 ...
- Nginx请求处理流程
因为 Nginx 运行在企业内网的最外层也就是边缘节点,那么他处理的的流量是其他应用服务器处理流量的数倍,甚至几个数量级,我们知道任何一种问题在不同的数量级下,他的解决方案是完全不同的,所以在 Ngi ...
- test20190829 神大校赛模拟
100+100+0=200,聪明搬题人题面又出锅了. 最短路径(path) 给定有向图,包含 n 个节点和 m 条有向边. 一条A 到 B 的路径是最短路径当且仅当不存在另一条从A 到 B 的路径比它 ...
- 阿里云部署java web
转载请注明出处http://blog.csdn.net/evankaka 摘要:本文主要讲了如何在阿里云上安装JDK.Tomcat以及其配置过程.最后以一个实例来演示在阿里云上部署Javaweb项目. ...
- Oracle-分析函数之排序值rank()和dense_rank()
聚合函数RANK 和 dense_rank 主要的功能是计算一组数值中的排序值. 在9i版本之前,只有分析功能(analytic ),即从一个查询结果中计算每一行的排序值,是基于order_by_cl ...
- Idea导入maven项目
1.idea中有项目的关闭项目 File>>close project 回到截图 下一步>下一步
- Leonardo的笔记本LA 3641——置换的乘法
题意 给出26个大写字母的置换 $B$,问是否存在一个置换 $A$,使得 $A^2=B$. 分析 首先,若A=BC,若B和C都能表示成两个相同循环的乘积,则A也能. 因为,不相交的循环的乘积满足交换律 ...
- 最小费用流模板(zkw与spfa)
"zkw" 费用流算法在哪些图上慢(摘自https://www.cnblogs.com/ECJTUACM-873284962/p/7744943.html) 实践中, 上面的这个算 ...
- 编程判断输入的字符是否为‘y’或‘Y’,若是,则输出‘yes’,否则输出‘no’
#include<stdio.h>void main(){ char ch; ch=getchar(); ch == 'y' || ch == 'Y' ? printf("yes ...