AnnotationConfigApplicationContext 通过调用注解Bean 定义读取器
AnnotatedBeanDefinitionReader 的register()方法向容器注册指定的注解Bean,注解Bean 定义读取器向容器注册注解Bean 的源码如下:
//注册多个注解Bean定义类
public void register(Class<?>... annotatedClasses) {for (Class<?> annotatedClass : annotatedClasses) {registerBean(annotatedClass);}
}//注册一个注解Bean定义类
public void registerBean(Class<?> annotatedClass) {doRegisterBean(annotatedClass, null, null, null);
}public <T> void registerBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier) {doRegisterBean(annotatedClass, instanceSupplier, null, null);
}public <T> void registerBean(Class<T> annotatedClass, String name, @Nullable Supplier<T> instanceSupplier) {doRegisterBean(annotatedClass, instanceSupplier, name, null);
}//Bean定义读取器注册注解Bean定义的入口方法
@SuppressWarnings("unchecked")
public void registerBean(Class<?> annotatedClass, Class<? extends Annotation>... qualifiers) {doRegisterBean(annotatedClass, null, null, qualifiers);
}//Bean定义读取器向容器注册注解Bean定义类
@SuppressWarnings("unchecked")
public void registerBean(Class<?> annotatedClass, String name, Class<? extends Annotation>... qualifiers) {doRegisterBean(annotatedClass, null, name, qualifiers);
}//Bean定义读取器向容器注册注解Bean定义类
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {//根据指定的注解Bean定义类,创建Spring容器中对注解Bean的封装的数据结构AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {return;}abd.setInstanceSupplier(instanceSupplier);//解析注解Bean定义的作用域,若@Scope("prototype"),则Bean为原型类型;//若@Scope("singleton"),则Bean为单态类型ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);//为注解Bean定义设置作用域abd.setScope(scopeMetadata.getScopeName());//为注解Bean定义生成Bean名称String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));//处理注解Bean定义中的通用注解AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);//如果在向容器注册注解Bean定义时,使用了额外的限定符注解,则解析限定符注解。//主要是配置的关于autowiring自动依赖注入装配的限定条件,即@Qualifier注解//Spring自动依赖注入装配默认是按类型装配,如果使用@Qualifier则按名称if (qualifiers != null) {for (Class<? extends Annotation> qualifier : qualifiers) {//如果配置了@Primary注解,设置该Bean为autowiring自动依赖注入装//配时的首选if (Primary.class == qualifier) {abd.setPrimary(true);}//如果配置了@Lazy注解,则设置该Bean为非延迟初始化,如果没有配置,//则该Bean为预实例化else if (Lazy.class == qualifier) {abd.setLazyInit(true);}//如果使用了除@Primary和@Lazy以外的其他注解,则为该Bean添加一//个autowiring自动依赖注入装配限定符,该Bean在进autowiring//自动依赖注入装配时,根据名称装配限定符指定的Beanelse {abd.addQualifier(new AutowireCandidateQualifier(qualifier));}}}for (BeanDefinitionCustomizer customizer : definitionCustomizers) {customizer.customize(abd);}//创建一个指定Bean名称的Bean定义对象,封装注解Bean定义类数据BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);//根据注解Bean定义类中配置的作用域,创建相应的代理对象definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);//向IOC容器注册注解Bean类定义对象BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
从上面的源码我们可以看出,注册注解Bean 定义类的基本步骤:
a、需要使用注解元数据解析器解析注解Bean 中关于作用域的配置。
b、使用AnnotationConfigUtils 的processCommonDefinitionAnnotations()方法处理注解Bean 定义类中通用的注解。
c、使用AnnotationConfigUtils 的applyScopedProxyMode()方法创建对于作用域的代理对象
d、通过BeanDefinitionReaderUtils 向容器注册Bean。
AnnotationConfigApplicationContext 通过调用注解Bean 定义读取器相关推荐
- Spring源码深度解析(郝佳)-学习-源码解析-基于注解bean定义(一)
我们在之前的博客 Spring源码深度解析(郝佳)-学习-ASM 类字节码解析 简单的对字节码结构进行了分析,今天我们站在前面的基础上对Spring中类注解的读取,并创建BeanDefinition做 ...
- AnnotationConfigUtils 处理注解Bean 定义类中的通用注解
AnnotationConfigUtils 类的processCommonDefinitionAnnotations()在向容器注册Bean 之前,首先对注解Bean 定义类中的通用Spring 注解 ...
- (转)Spring对注解(Annotation)处理源码分析1——扫描和读取Bean定义
1.从Spring2.0以后的版本中,Spring也引入了基于注解(Annotation)方式的配置,注解(Annotation)是JDK1.5中引入的一个新特性,用于简化Bean的配置,某些场合可以 ...
- 零配置 之 Spring注解实现Bean定义
转载自 零配置 之 12.3 注解实现Bean定义 --跟我学spring3 12.3 注解实现Bean定义 12.3.1 概述 前边介绍的Bean定义全是基于XML方式定义配置元数据,且在[1 ...
- spring源码解析bean定义五ContextNamespaceHandler一
2019独角兽企业重金招聘Python工程师标准>>> 前言 本文转自"天河聊技术"微信公众号 本次介绍ContextNamespaceHandler的prope ...
- 图片读取器和皮肤库设计
图片读取器和皮肤库设计 无论是图片读取器还是皮肤库设计,其实只是点到为止,没有深入做出很好的视觉效果,请见谅. 一.实验目的 1.结合实例,熟练分析并绘制UML类图: 2.熟练使用java实现两种常见 ...
- Struct2_定义拦截器并使用注解方式作用在Action的方法中
一.目的:通过在方法上加注解控制哪些方法需要登陆后才能访问 二.方式:利用拦截器判断用户是否登陆 三.实现步骤 定义配置文件 struts.xml添加节点 1 2 3 4 5 6 7 8 9 10 ...
- IO接口以太网低频工业RFID读写器|读取器CK-LR12-E00之Modbus TCP的寄存器定义与说明
IO接口以太网低频工业RFID读写器|读取器CK-LR12-E00是一款支持Modbus TCP通讯协议的工业以太网RFID数据读取设备,广泛应用于自动化MES系统领域,其MODBUS 寄存器为16b ...
- 【spring源码】二、bean定义、工厂
文章目录 一.基础概念 4.BeanFactory 和 ApplicationContext 5.FactoryBean 二.bean定义 "bean定义"是什么? 三.bean工 ...
最新文章
- MBR与GPT分区格式(实例-创建大于2TB的分区)
- python经典好书-推荐几本高质量的Python书籍--附github下载路径
- 【计算机网络】HTTP 与 HTTPS ( HTTP 在网络各个层级的传输过程 | HTTPS 工作流程 | HTTPS 弊端 )
- 延时消息_手把手实现一条延时消息
- SpringSecurity常用过滤器介绍
- JDBC连接MySQL数据库及示例
- Tomcat学习总结(10)——Tomcat多实例冗余部署
- oracle数据库listener开启和关闭trace文件的方法
- thinkpade470清灰_ThinkPad笔记本E470/T470/T470s禁用触控板教程
- 路由交换技术中生成树协议
- oracle EM导出AWR报告,AWR报告导出
- Android Studio一键汉化,分享一个自己写的小工具
- ET199加密狗是如何复制
- 喜欢听音乐应该买什么蓝牙耳机?音质好听的蓝牙耳机推荐
- centos6 php网页,centos怎样建网站
- 这10种赚钱方法,用手机就可以做,看看哪种适合你?
- 三星S508手机DIY图文教程全攻略
- 别把“IT信息化”不当“超级工程”
- 巴基斯坦圣诞节期间“毒酒”致42人死亡
- 中国建筑设计公司排名