# 第四章:Spring Bean 基础
## 什么是 `BeanDefinition`?
- `org.springframework.beans.factory.config.BeanDefinition`
- **BeanDefinition**是 Spring Framework 中定义 Bean 的配置元信息接口,包含:
- Bean 的类名
- Bean 行为配置元素,如作用域、自动绑定的模式(Autowired),生命周期回调等
- 其他 Bean 引用,又可称作合作者(collaborators)或者依赖(dependencies)
- 配置设置,比如 Bean 属性(Properties)
- BeanDefinition 构建
- 通过 `BeanDefinitionBuilder`
- 通过 `AbstractBeanDefinition` 以及派生类
Bean 名称生成器:`org.springframework.beans.factory.support.BeanNameGenerator`
![image-20220919202012564](assets/image-20220919202012564.png)
![image-20220919203842268](assets/image-20220919203842268.png)
* **多个上下文不唯一**
![image-20220919210150247](assets/image-20220919210150247.png)
## 注册 Spring Bean:
- BeanDefinition 注册
- XML 配置元信息
- ``
- Java 注解配置元信息
- `@Bean`
- `@Component`
- `@Import`
- Java API 配置元信息
- 命名方式:`BeanDefinitionRegistry#registerBeanDefinition(String,BeanDefinition)`
- 非命名方式:`BeanDefinitionReaderUtils#registerWithGeneratedName(AbstractBeanDefinition,Be`
`anDefinitionRegistry)`
- 配置类方式:`AnnotatedBeanDefinitionReader#register(Class...)`
- 外部单例对象注册
- Java API 配置元信息
- `SingletonBeanRegistry#registerSingleton`
Bean 实例化(Instantiation)
- 常规方式
- 通过构造器(配置元信息:XML、Java 注解和 Java API )
- 通过静态工厂方法(配置元信息:XML 和 Java API )
- 通过 Bean 工厂方法(配置元信息:XML和 Java API )
- 通过 `FactoryBean`(配置元信息:XML、Java 注解和 Java API )
- 特殊方式
- 通过 `ServiceLoaderFactoryBean`(配置元信息:XML、Java 注解和 Java API )
- 通过 `AutowireCapableBeanFactory#createBean(java.lang.Class, int, boolean)`
- 通过 `BeanDefinitionRegistry#registerBeanDefinition(String,BeanDefinition)`
## Bean 初始化(Initialization),同时存在时,顺序从上到下:
- `@PostConstruct` 标注方法
- 实现 `InitializingBean` 接口的 `afterPropertiesSet()` 方法
- 自定义初始化方法(**BeanDefinition**)
- XML 配置:``
- Java 注解:`@Bean(initMethod=”init”)`
- Java API:`AbstractBeanDefinition#setInitMethodName(String)`
Bean 延迟初始化(Lazy Initialization)
- XML 配置:``
- Java 注解:`@Lazy(true)`
Bean 销毁(Destroy),同时存在时,顺序从上到下:
- `@PreDestroy` 标注方法
- 实现 `DisposableBean` 接口的 `destroy()` 方法
- 自定义销毁方法
- XML 配置:``
- Java 注解:`@Bean(destroy=”destroy”)`
- Java API:`AbstractBeanDefinition#setDestroyMethodName(String)`
![image-20220921220443149](assets/image-20220921220443149.png)
## 面试题精选
1、如何注册一个spring bean?
![image-20220921221826319](assets/image-20220921221826319.png)
2、什么是spring beandefinition?
代码
3、spring容器是如何管理注册bean?
![image-20220921224726723](assets/image-20220921224726723.png)