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