Spring 基础
本节代码示例:spring-bean 模板
一、定义Spring Bean
-
什么是BeanDefinition?
-
BeanDefinition是Spring Framework中定义Bean的配置元信息接口。包含:
-
Bean 的 类名
-
Bean 行为配置、如作用域、自动绑定的模式,生命周期回调等
-
其他Bean引用,又可称合作者(collaborators) 或者依赖 (dependencies)
-
配置设置。 如:Bean属性(Properties)
-
-
二、 BeanDefinition 元信息
属性(Property) | 说明 |
---|---|
Class | Bean 全类名,必须是具体类,不能用抽象类或接口 |
Name | Bean的全称或ID(识别符) |
Scope | Bean的作用域(如:singleton、prototype等) |
Constructor arguments | Bean构造器参数(用于依赖注入) |
Properties | Bean属性设置(用于依赖注入) |
Autowriting mode | Bean自动绑定模式(如:通过名称byName,类型byType) |
Lazy initialzation mode | Bean延迟初始化模式(延迟和非延迟) |
initialzation mode | Bean回调方法名称 |
Destruction method | Bean销毁回调方法名称 |
代码演示参考:com.forjson.spring.bean.definition.BeanDefinitionCreationDemo
-
BeanDefinition构建
-
通过BeanDefinitionBuildler
-
//1.通过 BeanDefinitionBuilder 构建 User Class
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(User.class);
//设置属性值
beanDefinitionBuilder.addPropertyValue("id", 1L);
beanDefinitionBuilder.addPropertyValue("name", "howliked");
//获取BeanDefinition 并非终态,可以自定义修改
BeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
-
通过AbstractBeanDefinition以及派生类
//2.通过AbstractBeanDefinition以及派生类进行构建
GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();
genericBeanDefinition.setBeanClass(User.class);
//使用MutablePropertyValues 为对象设置值,支持链式调用
MutablePropertyValues mutablePropertyValues = new MutablePropertyValues();
mutablePropertyValues.add("id", 1L).add("name", "howliked");
genericBeanDefinition.setPropertyValues(mutablePropertyValues);
通常通过XML配置构建会比较多一点
三、命名Spring Bean
-
Bean的名称
-
每个Bean拥有的一个或多个标识符(identifiers),这些标识符在Bean所在的容器必须是唯一的。通常,一个Bean仅有一个标识符,如果需要额外的,可考虑使用别名(Alias)来扩充
-
在基于XML配置中,开始人员可用id或name属性来规定Bean的标识符。通常Bean的标识符由字母组成,允许出现特殊字符。如果要想引入Bean的别名的话,可在Name属性使用半角逗号(",")或分号(";")来间隔。
-
Bean的id或name属性并非必须规定,如果留空的话,容器会为Bean自动生成一个唯一的名称。Bean的命名尽管没有限制,不过官方建议采用驼峰的方式,更符合Java的命名约定。
-
-
Bean 名称生成器 (BeanNameGenerator)
-
由Spring Framework 2.0.3引入,框架内建两种实现:
-
DefaultBeanNameGenerator:默认通用BeanNameGenerator实现
-
AnnotationBeanNameGenerator:基于注解扫描的BeanNameGenerator实现
-
-
四、Spring Bean的别名
代码演示参考: com.forjson.spring.bean.definition.BeanAliasDemo
-
Bean 别名(Alias)的价值
代码演示参考: com.forjson.spring.bean.definitions.ApiBeanDefinitionDemo
-
复用现有的BeanDefinition
-
更具有场景化的命名方法
五、注册 Spring Bean
代码演示参考: com.forjson.spring.bean.definitions.ApiBeanDefinitionDemo
BeanDefinition注册
-
XML配置元信息
-
<bean name="" .../>
-
Java注解配置元信息
-
@Bean
-
@Component
-
@Import
-
-
-
Java Api配置元信息
-
命名方式: BeanDefinitionRegistry#registerBeanDefinition(String,BeanDefiition);
-
非全名方式: BeanDefinitionReaderUtils#registerWithGeneratedName(AbstractBeanDefition,BeanDefinitionRegistry);
-
注解方式: AnnotatedBeanDefinitionReader#register(Class...);
-
-
六、 实例化Spring Bean
代码演示参考: com.forjson.spring.bean.instantiation.BeanInstantiationDemo
- Bean的实例化(Instantiation)
- 常规方式
-
通过构造器(配置元信息:XML、Java注解和JavaAPI)
-
通过静态工厂(配置元信息:XML和Java API)
-
通过Bean工厂方法(配置元信息:XML和Java API)
-
通过FactoryBean(配置元信息:XML、Java注解和Java API)
-
- 常规方式
-
特殊方式
演示代码:com.forjson.spring.bean.instantiation.SpecialBeanInstantiationDemo
-
通过ServiceLoaderFactoryBean(配置元信息:XML、Java注解和JavaAPI)
-
通过AutowireCapableBeanFactory#createBean(java.lang.Class,int,boolean)
-
通过BeanDefinitionRegistry#registerBeanDefinition(配置元信息:XML、Java注解和JavaAPI)
-
七、初始化 Spring Bean
代码演示参考: com.forjson.spring.bean.definition.BeanInitializationDemo
- Bean初始化(Bean Initialization)
-
@PostConstruct 标注方法
- 实现InitializingBean的afterPropertiesSet()
-
自定义初始化方法
-
XML配置文件: <bean init-method="init" />
-
Java注解: @Bean(initMethod="init")
-
Java Api方式:AbstractBeanDefinition#setInitMethodName(String)
-
-
-
思考:假设以上三种方式均在同一Bean中定义,那么这些方法的执行顺序是什么?
八、延迟初始化 Spring Bean
代码演示参考: com.forjson.spring.bean.definition.BeanLazyInitializationDemo
- Bean的延迟初始化(Lazy Initialization)
-
XML 配置 <bean lazy-init="true" />
-
Java 注解 @Lazy
-
-
思考: 当某个Bean定义为延迟初始化,那么Spring容器返回的对象与延迟的对象存在怎样的差异?
org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization
-
非延迟初始化 在Spring应用上下文启动后,初始化
-
延迟初始化,当在第一次依赖查找时,初始化
九、销毁 Spring Bean
本节参考代码:com.forjson.spring.bean.definition.BeanDestoryDemo
-
Bean 的销毁 (Destory)
-
@PreDestory 方法
-
实现DisposableBean 接口的Destory()方法
-
自定义初始化方法
-
Java Api方式:AbstractBeanDefinition#setDestoryMethodName(String)
-
Java注解: @Bean(destory="destroy")
-
XML配置文件: <bean destory="destory" />
-
-
-
思考: 当某个Bean定义了销毁方法时,这些方法的执行顺序是怎样的?
-
什么时候调用销毁方法 ?
-
上下文容器关闭时,调用销毁方法
-
org.springframework.context.support.AbstractApplicationContext#close#destroyBeans
-
十、垃圾回收 Spring Bean
代码演示参考:com.forjson.spring.bean.definition.BeanGarbageCollectionDemo
-
Bean的垃圾回收(GC)
-
关闭Spring 容器(应用上下文)
-
执行GC
-
Spring Bean覆盖finalize()方法被回调
-
十一、面试题精选
- Spring是如何注册一个Bean的?
-
BeanDefinition 和 外部单体Bean注册
外部单体Bean注册参考代码: SingletonBeanRegisterDemo
- 什么是Spring BeanDefinition?
-
Spring BeanDefinition 是Spring Bean的配置元信息
-