zoukankan      html  css  js  c++  java
  • 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 

     然后通过工具类进行注册:

     然后进行注册:

    
    

    画图整理:

  • 相关阅读:
    linux下启动和关闭网卡命令及DHCP上网
    python 编码问题
    paddlepaddle
    Convolutional Neural Network Architectures for Matching Natural Language Sentences
    deep learning RNN
    Learning Structured Representation for Text Classification via Reinforcement Learning 学习笔记
    Python IO密集型任务、计算密集型任务,以及多线程、多进程
    EM 算法最好的解释
    tensorflow 调参过程
    tensorflow 学习纪录(持续更新)
  • 原文地址:https://www.cnblogs.com/toov5/p/11223463.html
Copyright © 2011-2022 走看看