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
然后通过工具类进行注册:
然后进行注册:
画图整理: