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 

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

 

 然后进行注册:

 


画图整理:

posted @ 2019-07-21 23:50  toov5  阅读(1132)  评论(0编辑  收藏  举报