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

  • @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. nginx配置白名单

    配置如下: http模块: http { include mime.types; default_type application/octet-stream; #log_format main '$r ...

  2. Tomcat默认连接超时时间

    秒=1小时 2. 在web.xml中通过参数指定: xml 代码 <session-config>         <session-timeout>30</sessio ...

  3. restful接口规范 | 基于restful的原生django接口

    restful接口规范 接口 接口:联系两个物质的媒介,完成信息交互 web程序中:联系前台页面与后台数据库的媒介 web接口组成: - url:长得像返回数据的url链接 - 请求参数:前台按照指定 ...

  4. python通过globals()函数获取全局变量,并销毁全局变量

    如果想获取python程序中所有全局变量的信息,并将其销毁,可以定义如下函数 def clear(): for key, value in globals().items(): if callable ...

  5. Java【基础学习】之暴力求素数【用数组返回】

    Java[基础学习]之暴力求素数[用数组返回] */ import java.util.*; public class Main{ public static void main(String[] a ...

  6. Greenplum FTS故障检测原理

    前言 FTS(Fault Tolerance Serve)是GreenPlum中的故障检测服务,是保证GP高可用的核心功能.GreenPlum的Segment的健康检测及HA是由GP Master实现 ...

  7. 转 Storm JAVA_HOME is incorrectly set.

    问题可能有两个原因: 1.在环境变量中未设置JAVA_HOME变量名称. 解决办法: 在环境变量中添加. 或者在storm中的bin文件下有一个storm-config.cmd,使用文本打开,查询JA ...

  8. [分享]Passcape Software - Windows Password Recovery

    [分享]Passcape Software - Windows Password Recovery https://bbs.pediy.com/thread-245965.htm   [[other] ...

  9. flutter报错:NoSuchMethodError: The method '>' was called on null.

    写了个list,发现出不来,报错 flutter: Another exception was thrown: RenderBox was not laid out: _RenderScrollSem ...

  10. codecs 1264 芳香数

    1264 芳香数 题目描述 Description This question involves calculating the value of aromatic numbers which are ...