前言: 主要了解的内容有如下几点:

  • @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的更多相关文章

  1. Spring5源码分析(1)设计思想与结构

    1 源码地址(带有中文注解)git@github.com:yakax/spring-framework-5.0.2.RELEASE--.git Spring 的设计初衷其实就是为了简化我们的开发 基于 ...

  2. Spring5源码分析之Bean生命周期

    Spring Bean生命周期的构成 Bean的完整生命周期经历了各种方法调用,这些方法可以划分为以下几类: Bean自身的方法: 这个包括了Bean本身调用的方法和通过配置文件中<bean&g ...

  3. Spring5源码分析之启动类的相关接口和注解

    一些基础但是核心的知识总结: Spring Boot项目启动的时候需要加@Configuration. @ComponentScan @Configuration + @Bean 把第三方jar包注入 ...

  4. spring5源码分析系列(三)——IOC容器的初始化(一)

    前言: IOC容器的初始化包括BeanDefinition的Resource定位.载入.注册三个基本过程. 本文以ApplicationContext为例讲解,XmlWebApplicationCon ...

  5. spring5源码分析系列(二)——spring核心容器体系结构

    首先我们来认识下IOC和DI: IOC(Inversion of Control)控制反转:控制反转,就是把原先代码里面需要实现的对象创建.依赖的代码,反转给容器来帮忙实现.所以需要创建一个容器,并且 ...

  6. spring5源码分析系列(一)——spring5框架模块

    spring总共大约20个模块,这些模块被整合在核心容器(Core Container).AOP和设备支持.数据访问及集成.Web.报文发送.Test 6个模块集合. 组成Spring框架的每个模块集 ...

  7. Spring5深度源码分析(三)之AnnotationConfigApplicationContext启动原理分析

    代码地址:https://github.com/showkawa/spring-annotation/tree/master/src/main/java/com/brian AnnotationCon ...

  8. 5.2 Spring5源码--Spring AOP源码分析二

    目标: 1. 什么是AOP, 什么是AspectJ 2. 什么是Spring AOP 3. Spring AOP注解版实现原理 4. Spring AOP切面原理解析 一. 认识AOP及其使用 详见博 ...

  9. 5.2 spring5源码--spring AOP源码分析二--切面的配置方式

    目标: 1. 什么是AOP, 什么是AspectJ 2. 什么是Spring AOP 3. Spring AOP注解版实现原理 4. Spring AOP切面原理解析 一. 认识AOP及其使用 详见博 ...

随机推荐

  1. P4315 月下“毛景树”[树剖]

    题目描述 毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园. 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校园里. 爬啊爬~爬啊爬毛毛虫爬到了一颗小小的"毛景树&quo ...

  2. node gyp编译所需要的环境

    安装ms的build工具包,自带python npm install --global --production windows-build-tools

  3. grep命令选项

    -c:只输出匹配行的计数. -I:不区分大 小写(只适用于单字符). -h:查询多文件时不显示文件名. -l:查询多文件时只输出包含匹配字符的文件名. -n:显示匹配行及 行号. -s:不显示不存在或 ...

  4. ClickHouse 分布式高可用集群搭建(转载)

    一.ClickHouse安装方式: 源码编译安装 Docker安装 RPM包安装 为了方便使用,一般采用RPM包方式安装,其他两种方式这里不做说明. 二.下载安装包 官方没有提供rpm包,但是Alti ...

  5. b/s实现大文件上传分片上传断点续传

    关键部分 前端用file.slice()分块 前端用FileReader获取每一分块的md5值 后端用MultipartFile接受分块文件 后端用FileOutputStream拼装分块文件 话不多 ...

  6. Win32 Error

    一.Win32错误 也就是Win32子系统产生的错误.当我们在自己的代码里调用Windows系统的API函数,系统执行API内部代码,当API内部代码出现错误,会将预先定义好的错误代码写到调用这个AP ...

  7. qt截图grapWindow,操作系统剪切版QClipBoard实现进程间通信

    QPixmap::grapWindow(winID) 存放一个图片QDesktopWidget 获得当前程序所在窗口id pid每个窗口有winID() // 3pixmap scaled 比例缩放 ...

  8. Processing 2.1.1 无法使用video和movie问题解决方案

    升级到2.1.1后,尝试着运行了一下sample中的video和movie,结果都报错,上网搜了一下,找到解决方法. 1. 首先来看movie的错误,如下: JNA: Callback org.gst ...

  9. CODE FESTIVAL 2016 qual B题解

    传送门 \(A\) 什么玩意儿-- const char t[]={"0CODEFESTIVAL2016"}; char s[25];int res; int main(){ sc ...

  10. Oracle,regexp_replace函数,replace函数

    replace函数(不知支持正则表达式)语法: replace(原字段,“原字段旧内容“,“原字段新内容“,) select replace(原字段,'原字段旧内容','原字段新内容') from T ...