# 第四章: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`


* **多个上下文不唯一**

## 注册 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)`

## 面试题精选
1、如何注册一个spring bean?

2、什么是spring beandefinition?
代码
3、spring容器是如何管理注册bean?
