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