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及其使用 详见博 ...
随机推荐
- java(Hello World) 常量 变量和注意事项
一.java的入门程序 java语言的简单介绍 关于java语言的特点:(1) 简单性和c++相比,java没有头文件.指针.运算符重载等,java语言相当于是一个比较纯净版的c++.(2) 面对对象 ...
- C# 8.0 的新特性( NET Framework 4.8 与 Visual Studio 2019 )
C#8.0 于 2019年4月 随 .NET Framework 4.8 与 Visual Studio 2019 一同发布 使用VS2019体检C#8.0新功能: 编辑.csproj文件,添加如下代 ...
- Spring源码窥探之:FactoryBean
1. 定义Fish实体类 /** * @author 70KG * @Title: Fish * @Description: * @date 2018/7/22下午5:00 * @From www.n ...
- 常见的C语言编程规范
头文件: 1.头文件中适合放置接口的声明,不适合放置实现. 2.头文件应向稳定的方向包含,产品依赖于平台,平台依赖于标准库. 3. .c/.h文件禁止包含用不到的头文件. 4.每一个.c文件应有一个同 ...
- python爬取动态网页数据,详解
原理:动态网页,即用js代码实现动态加载数据,就是可以根据用户的行为,自动访问服务器请求数据,重点就是:请求数据,那么怎么用python获取这个数据了? 浏览器请求数据方式:浏览器向服务器的api(例 ...
- (转载) 从0开始搭建SQL Server AlwaysOn 第四篇(配置异地机房节点)
这一篇是从0开始搭建SQL Server AlwaysOn 的第四篇,这一篇开始搭建异地机房节点 注意点1 注意异地节点最好至少有2个AG节点,否则在本地节点进行手动故障转移的时候会出现仲裁警告,提示 ...
- ML,DL核心数学及算法知识点总结
ML,DL核心数学及算法知识点总结:https://mp.weixin.qq.com/s/bskyMQ2i1VMNiYKIvw_d7g
- php 数组的计算
数组是我们最常用到的类型,那如何计算某个一维数组的个数呢.其实我们可以用到我们之前学过的数学函数里面的一个:count(). 我们来看看count函数的用法: int count ( mixed $变 ...
- 4-STM32物联网开发WIFI(ESP8266)+GPRS(Air202)系统方案升级篇(远程升级WIFI内部程序)
https://www.cnblogs.com/yangfengwu/p/10360618.html 演示视频: https://www.bilibili.com/video/av54894356/ ...
- leetcode解题报告(24):Pascal's TriangleII
描述 Given an index k, return the kth row of the Pascal's triangle. For example, given k = 3, Return [ ...