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

  • @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. 软件测试过程中如何区分什么是功能bug,什么是需求bug,什么是设计bug?

    问题描述: 测试过程中如何区分什么是功能bug,什么是需求bug,什么是设计bug? 精彩答案: 会员 土土的豆豆: 本期问题其实主要是针对不同方面或纬度上对于bug的一个归类和定位. 个人认为,从软 ...

  2. C语言实验1—— C中的指针和结构体

    问题 实现一个算法,检测单链表中是否有环,如果有环还要得到环的入口. 分析 判断是否有环:快慢指针法(也叫“龟兔赛跑”),慢指针每次移动一位,快指针每次移动两位,如果有环,他们一定会相遇. 求环的入口 ...

  3. LightOJ - 1246 - Colorful Board(DP)

    链接: https://vjudge.net/problem/LightOJ-1246 题意: You are given a rectangular board. You are asked to ...

  4. Tensorflow细节-P42张量的概念及使用

    1.运行以下代码 import tensorflow as tf a = tf.constant([1.0, 2.0], name="a") b = tf.constant([2. ...

  5. SPA项目开发--表单验证、增删改

    1. 表单验证 Form组件提供了表单验证的功能,只需要通过 rules 属性传入约定的验证规则,   并将Form-Item的prop属性设置为需校验的字段名即可      <el-form- ...

  6. php流程控制 之循环语句的使用

    循环语句的使用 王同学需要反复往返于北京和大连,就是典型的循环结构.假设王思总投资这个项目需要往返大连100次,每次往返都王同学都会计数一次.难道我们写一百遍同样的代码?显然对于智商极高的程序员来说不 ...

  7. noi.ac #42 模拟

    \(des\) 二维平面上存在 \(m\) 个点,每个点会对该点的 \(8\) 个方向上的最近的点产生影响 问每个点会被影响多少次 \(sol\) 过每个点会产生 \(4\) 条线段 保存每条线段的斜 ...

  8. 洛谷 P2661 信息传递 题解

    P2661 信息传递 题目描述 有 \(n\) 个同学(编号为 \(1\) 到 \(n\) )正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为 \(i\) 的同学的信息传 ...

  9. LibreOJ #528. 「LibreOJ β Round #4」求和

    二次联通门 : LibreOJ #528. 「LibreOJ β Round #4」求和 /* LibreOJ #528. 「LibreOJ β Round #4」求和 题目要求的是有多少对数满足他们 ...

  10. 记录一个webstorm的设置或者说小技巧

    在 html 的元素中,如果输入属性,默认会填充 引号,在 react 书写中非常不方便. 其中的JSX很多时候是不需要 quotation 的,只是需要一个 括号 {} 即可. 自己找了下webst ...