SpringBean 基础
2022-07-01 17:35:32 7 举报
AI智能生成
SpringBean基础,Bean的元信息、Bean的定义、Bean的注册、实例化、属性填充、初始化、销毁等
作者其他创作
大纲/内容
定义 Spring Bean
什么是 Bean Definition ?
Bean Definition 是 Spring Framework 中定义 Bean 配置元信息接口<br>
包含以下内容
Bean 的类名
Bean 的行为配置元素,如作用域,自动绑定模式,生命周期等<br>
其他 Bean 引用,又可称之为合作者或者依赖
配置设置,比如 Bean 的属性
Bean Definition 元信息<br>
图表
Bean Definition 构建
通过 BeanDefinitionBuilder创建<br>
通过 AbstractBeanDefinition 以及派生类<br>
命名 Spring Bean
Bean 的名称<br>
每个 Bean 拥有一个或多个标识符(identifiers),这些标识符在 Bean 所在的容器必须是 唯一的。通常,一个 Bean 仅有一个标识符,如果需要额外的,可考虑使用别名(Alias)来 扩充
在基于 XML 的配置元信息中,开发人员可用 id 或者 name 属性来规定 Bean 的 标识符。通 常 Bean 的 标识符由字母组成,允许出现特殊字符。如果要想引入 Bean 的别名的话,可在 name 属性使用半角逗号(“,”)或分号(“;”) 来间隔
Bean 的 id 或 name 属性并非必须制定,如果留空的话,容器会为 Bean 自动生成一个唯一 的名称。Bean 的命名尽管没有限制,不过官方建议采用驼峰的方式,更符合 Java 的命名约 定。
<div><span style="mso-spacerun:'yes';font-size:14.05pt;font-family:宋体;color:rgb(0,0,0);"></span></div><div>Bean 名称生成器<br></div>
接口<br>
BeanNameGenerator
实现
默认通用 BeanNameGenerator 实现<br>
基于注解扫描的AnnotationBeanNameGenerator<br>
源码分析
Spring Bean 的别名
Bean 别名(Alias)的价值<br>
复用现有的 BeanDefinition<br>
更具有场景化的命名方法,比如:<br> <alias name="myApp-dataSource" alias="subsystemA-dataSource"/> <br><alias name="myApp-dataSource" alias="subsystemB-dataSource"/>
Bean别名使用案例
XML配置
别名对象获取案例
注册 Spring Bean
XML 配置元信息<br>
Java 注解配置元信息<br>
@Bean
@Component
@Import
案例
使用Java注解注册 Bean Definition
Java API 配置元信息
命名方式
BeanDefinitionRegistry#registerBeanDefinition(String,BeanDefinition)
非命名方式<br>
BeanDefinitionReaderUtils#registerWithGeneratedName(AbstractBeanDefinition,BeanDe finitionRegistry)
<div><span style="mso-spacerun:'yes';font-size:12pt;font-family:宋体;color:rgb(0,0,0);"></span></div><div>配置类方式<br></div>
AnnotatedBeanDefinitionReader#register(Class...)<br>
实例化 Spring Bean<br>
常规方式
通过构造器(配置元信息:XML、Java 注解和 Java API )<br>
XML配置
User对象添加无参构造
获取Bean实例
通过静态工厂方法(配置元信息:XML 和 Java API )<br>
XML配置
User对象添加静态方法
获取Bean实例
通过 Bean 工厂方法(配置元信息:XML和 Java API )<br>
XML配置
添加实例工厂接口
添加默认工厂实现
获取Bean实例
通过 FactoryBean(配置元信息:XML、Java 注解和 Java API )
XML配置
添加FactoryBean实现类
获取Bean实例
特殊方式
通过 ServiceLoaderFactoryBean(配置元信息:XML、Java 注解和 Java API )
将要实例化的工厂类配置到META-INF/services下,并以工厂类全路径+名称为文件名创建文件
获取使用
通过 AutowireCapableBeanFactory#createBean(java.lang.Class, int, boolean)
将要实例化的工厂类配置到META-INF/services下,并以工厂类全路径+名称为文件名创建文件
将工厂类注入到 IoC Container 中
获取使用
通过 BeanDefinitionRegistry#registerBeanDefinition(String,BeanDefinition)
初始化 Spring Bean<br>
@PostConstruct 标注方法<br>
添加初始化方法
获取使用
实现 InitializingBean 接口的 afterPropertiesSet() 方法<br>
添加初始化方法<br>
获取使用
自定义初始化方法<br>
XML 配置:<bean init-method=”init” ... /><br>
Java 注解:@Bean(initMethod=”init”)<br>
Java API:AbstractBeanDefinition#setInitMethodName(String)
初始化执行顺序
<br>
延迟初始化 Spring Bean
XML 配置:<bean lazy-init=”true” ... /><br>
Java 注解:@Lazy(true)
Java API: AbstractBeanDefinition#setLazyInit<br>
当某个 Bean 定义为延迟初始化,那么,Spring 容器返回的对象与非延迟的对象存在怎样的差异?
lazy
Bean 的初始化会在Spring容器启动以后获取对象时执行
no-lazy
Bean 的初始化会在Spring容器启动之前执行
销毁 Spring Bean
@PreDestroy 标注方法
实现 DisposableBean 接口的 destroy() 方法
自定义销毁方法
XML 配置:<bean destroy=”destroy” ... /><br>
Java 注解:@Bean(destroy=”destroy”)<br>
Java API:AbstractBeanDefinition#setDestroyMethodName(String)
假设以上三种方式均在同一 Bean 中定义,那么这些方法的执行顺序是怎样?
先执行Java注解@PreDestroy、之后为DisposableBean#destroy(),最后为自定义方法
销毁 Spring Bean 是什么时候触发的?
触发时机为调用close方法,close方法中会去调用这几个方法
垃圾回收 Spring Bean
执行流程
关闭 Spring 容器(应用上下文)<br>
执行 GC<br>
Spring Bean 覆盖的 finalize() 方法被回调
案例
关闭容器并执行GC
重写finalize方法
在ApplicationContext关闭之前,GC是不会回收Bean的,纵然显示的调用也是如此。而在ApplicationContext关闭之后,JVM会在垃圾回收周期中去回收掉Bean。
面试题
如何注册一个 Spring Bean?
使用BeanDefinition注册或者XML配置、Java注解、JavaApi
使用外部单体对象注册
什么是 Spring BeanDefinition?<br>
需要放进IoC容器对象的元信息,包括
SCOPE作用域<br>
ROLE角色,该Bean扮演的是什么角色,如应用Bean,框架使用的Bean,普通Bean
Parent父类<br>
Lazy是否懒加载<br>
DependsOn依赖的类有那些
AutowireCandidate是否自动装配
Primary是否为主要的,设置为true的情况下,有个同类型的Bean,getBean方法不会报错,而是获取Primary标注的Bean
ConstructorArgumentValues构造器参数
InitMethodName对象初始化方法名称
DestroyMethodName对象销毁方法名称<br>
Spring 容器是怎样管理注册 Bean<br>
答:答案将在后续专题章节详细讨论,如:IoC 配置元信息读取和解析、依 赖查找和注入以及 Bean 生命周期等。<br>
0 条评论
下一页