浅谈@Configuration注解原理
@Configuration注解实现类为AnnotationConfigApplicationContext
/*** Create a new AnnotationConfigApplicationContext that needs to be populated* through {@link #register} calls and then manually {@linkplain #refresh refreshed}.*/public AnnotationConfigApplicationContext() {this.reader = new AnnotatedBeanDefinitionReader(this);this.scanner = new ClassPathBeanDefinitionScanner(this);}/*** Create a new AnnotationConfigApplicationContext with the given DefaultListableBeanFactory.* @param beanFactory the DefaultListableBeanFactory instance to use for this context*/public AnnotationConfigApplicationContext(DefaultListableBeanFactory beanFactory) {super(beanFactory);this.reader = new AnnotatedBeanDefinitionReader(this);this.scanner = new ClassPathBeanDefinitionScanner(this);}/*** Create a new AnnotationConfigApplicationContext, deriving bean definitions* from the given component classes and automatically refreshing the context.* @param componentClasses one or more component classes — for example,* {@link Configuration @Configuration} classes*/public AnnotationConfigApplicationContext(Class<?>... componentClasses) {this();register(componentClasses);refresh();}/*** Create a new AnnotationConfigApplicationContext, scanning for components* in the given packages, registering bean definitions for those components,* and automatically refreshing the context.* @param basePackages the packages to scan for component classes*/public AnnotationConfigApplicationContext(String... basePackages) {this();scan(basePackages);refresh();}
有4种构造器
- 初始化AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner对象,它需要通过注册调用填充,然后手动刷新。
- 先使用给定的DefaultListableBeanFactory创建一个新的AnnotationConfigApplicationContext然后初始化AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner对象
- 创建一个新的AnnotationConfigApplicationContext,从给定的组件类派生bean定义,并自动刷新上下文
- 创建一个新的AnnotationConfigApplicationContext,扫描给定包中的组件,为这些组件注册bean定义,并自动刷新上下文。
我们看里面最重要的几个方法
1.setEnvironment(将给定的自定义环境传播到底层的AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner。)
@Overridepublic void setEnvironment(ConfigurableEnvironment environment) {super.setEnvironment(environment);this.reader.setEnvironment(environment);this.scanner.setEnvironment(environment);}
2.setBeanNameGenerator(设置Bean名称,任何对这个方法的调用必须发生在调用register(Class…)和/或scan(String…)之前)
public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) {this.reader.setBeanNameGenerator(beanNameGenerator);this.scanner.setBeanNameGenerator(beanNameGenerator);getBeanFactory().registerSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR, beanNameGenerator);}
3.setScopeMetadataResolver(设置Bean的作用域,即判断注册的Bean 是原生类型(prototype)还是单例(singleton)类型,任何对这个方法的调用必须发生在调用register(Class…)和/或scan(String…)之前。)
public void setScopeMetadataResolver(ScopeMetadataResolver scopeMetadataResolver) {this.reader.setScopeMetadataResolver(scopeMetadataResolver);this.scanner.setScopeMetadataResolver(scopeMetadataResolver);}
4.register(注册一个或多个要处理的组件类。 注意,为了让上下文完全处理新类,必须调用refresh())
@Overridepublic void register(Class<?>... componentClasses) {Assert.notEmpty(componentClasses, "At least one component class must be specified");this.reader.register(componentClasses);}
5.scan(在指定的基包中执行扫描。 请注意,为了让上下文完全处理新类,必须调用refresh()。)
@Overridepublic void scan(String... basePackages) {Assert.notEmpty(basePackages, "At least one base package must be specified");this.scanner.scan(basePackages);}
6.registerBean从给定的bean类注册一个bean,使用给定的元数据信息获取一个新实例(通常声明为lambda表达式或方法引用),也可以定制它的bean定义元数据(通常声明为lambda表达式)。 这个方法可以被重写,以适应所有registerBean方法的注册机制(因为它们都委托给这个方法)。
参数: beanName—bean的名称(可能为空) bean class—bean的类 Supplier——用于创建bean实例的回调函数(在null的情况下,解析一个公共构造函数来自动连接) customizer——一个或多个用于定制工厂的BeanDefinition的回调函数,例如设置一个lazy-init或主标志
@Overridepublic <T> void registerBean(@Nullable String beanName, Class<T> beanClass,@Nullable Supplier<T> supplier, BeanDefinitionCustomizer... customizers) {this.reader.registerBean(beanClass, beanName, supplier, customizers);}
总结
1.通过构造器初始化初始化AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner对象
2.在调用register()之前去,调用setScopeMetadataResolver()设置Bean的作用域并调用setBeanNameGenerator()设置Bean的名称
3.然后调用refresh()方法刷新配置文件(可以是xml配置也可以是其他)
4.最后调用registerBean()注册到容器中
浅谈@Configuration注解原理相关推荐
- 浅谈:Spring Boot原理分析,切换内置web服务器,SpringBoot监听项目(使用springboot-admin),将springboot的项目打成war包
浅谈:Spring Boot原理分析(更多细节解释在代码注释中) 通过@EnableAutoConfiguration注解加载Springboot内置的自动初始化类(加载什么类是配置在spring.f ...
- 浅谈“三层结构”原理与用意(转帖)
浅谈"三层结构"原理与用意 序 在刚刚步入"多层结构"Web应用程序开发的时候,我阅读过几篇关于"asp.net三层结构开发"的文章.但其多 ...
- 浅谈前端路由原理hash和history
浅谈前端路由原理hash和history
- svc的参考文献_浅谈SVC的原理及作用
浅谈 SVC 的原理及作用 超(特)高压运行检修公司 自贡中心 涂洪骏 摘要: 介绍了静止补偿器 (SVC) 的工作特性.基本原理.运行方式,重点针对 SVC 的作用进行了分析. 关键词 :静止补偿器 ...
- 浅谈Wi-Fi渗透--原理篇
浅谈Wi-Fi渗透–原理篇 在这个手机比人多的移动时代,无线网络Wi-Fi遍布每个角落,殊不知隐藏其中的风云涌动 广义上无线网络应用类型如下,今天的文章就聚焦于 WLAN的一种无线局域网技术--Wi- ...
- 浅谈会话劫持原理及实践
<监视你的一举一动> ---浅谈会话劫持原理及实践 前言 通常,大家所说的入侵,都是针对一台主机,在获得管理员权限后,就很是得意:其实,真正的入侵是占领整个内部网络.针对内部网络的攻击方法 ...
- 浅谈实时数据库系统原理及其应用
浅谈实时数据库系统原理及其应用 孙俊彦 苏州大学计算机科学与技术学院 摘要: 现代的工程和时间关键型应用对数据库的实时性和对数据直接分析和处理的能力要求特别高,单纯的传统关系数据库已经不能满足需要 ...
- 浅谈Openstack网络原理(openstack无法上网?)
浅谈Openstack网络 本版本为Stein版本,采用OVS网络 测试环境:1控制节点,2个计算节点 目录 浅谈Openstack网络 一.网络结构图 二.OVS分析 三.DHCP服务 四.Rout ...
- 浅谈Spring注解
Spring目前的趋势是使用注解结合Java代码而不是配置来定义行为.属性.功能.规则和扩展点,因此梳理注解也是梳理Spring功能点的很好的方式,全面的梳理可以补足我们知识点的漏洞. 查找所有注解 ...
- 独家 | 浅谈强化学习原理(附代码链接)
作者:Michel Kana 翻译:王琦 校对:王雨桐 本文约4900字,建议阅读15分钟. 本文介绍了强化学习的基本原理,并通过代码实例来讲解如何找到最优策略. Google在2017年年底发布了A ...
最新文章
- java vector_Java Vector sureCapacity()方法与示例
- 苹果x屏幕出现一条绿线_部分用户反映苹果 iPhone 12 屏幕出现划痕 - iPhone 12
- c语言中汉字属于什么类型_练字应该练什么之:汉字基本结构的类型
- 大数据之-Hadoop之HDFS的API操作_文件下载案例---大数据之hadoop工作笔记0058
- 完全卸载mysql步骤
- 在华为服务器 RH 2288H V2上装 windows 2008
- 人脸识别管理系统php源码,完整的人脸识别系统源代码
- Cadence导出带有书签和链接的PDF原理图
- 联发科MT2503芯片资料MT2503原理图
- oppo手机硬件测试软件,OPPO怎么测试手机硬件,只需要做这一步,进入工程模式...
- 电脑自带的cmd/Powershell连接远程服务器(实用技巧)
- Debain查看ip地址
- 走访名校名企,助力生涯规划
- moses 编译_Moses 训练步骤
- 以智能卡平台为硬件的嵌入式加密IC的优势
- 【微信小程序】不支持使用本地图片设置背景图片解决方法
- AcWing 844.走迷宫
- 手把手教你搭建SpringCloudAlibaba之Nacos服务配置中心
- 仿 Lenovo商城首页
- python画点的函数_【Python】matplotlib绘图 - scatter、plot函数画离散点(带有边线)...