Spring(04)Spring Bean 基础

Spring(04)Spring Bean 基础

Spring 核心编程思想目录:https://www.cnblogs.com/binarylei/p/12290153.html

1. 定义 Spring Bean

BeanDefinition 是 Spring Framework 中定义 Bean 的配置元信息接口,包含:

  • Bean 的类名
  • Bean 行为配置元素,如作用域、自动绑定的模式,生命周期回调等
  • 其他 Bean 引用,又可称作合作者(collaborators)或者依赖(dependencies)
  • 配置设置,比如 Bean 属性(Properties)

2. BeanDefinition 元信息

属性(Property) 说明
Class Bean 全类名,必须是具体类,不能用抽象类或接口
Name Bean 的名称或者ID
Scope Bean 的作用域(如:singleton、prototype 等)
Constructor arguments Bean 构造器参数(用于依赖注入)
Properties Bean 属性设置(用于依赖注入)
Autowiring mode Bean 自动绑定模式(如:通过名称byName)
Lazy initialization mode Bean 延迟初始化模式(延迟和非延迟)
Initialization method Bean 初始化回调方法名称
Destruction method Bean 销毁回调方法名称

BeanDefinition 构建

  • BeanDefinitionBuilder
  • AbstractBeanDefinition 以及派生类

3. 命名 Spring Bean

3.1 Bean 的名称

每个 Bean 拥有一个或多个标识符(identifiers),这些标识符在 Bean 所在的容器必须是唯一的。通常,一个Bean 仅有一个标识符,如果需要额外的,可考虑使用别名(Alias)来扩充。

在基于 XML 的配置元信息中,开发人员可用 id 或者 name 属性来规定 Bean 的标识符。通常 Bean 的标识符由字母组成,允许出现特殊字符。如果要想引入 Bean 的别名的话,可在 name 属性使用半角逗号(“,”)或分号(“;”) 来间隔。

Bean 的 id 或name 属性并非必须制定,如果留空的话,容器会为 Bean 自动生成一个唯一的名称。Bean 的命名尽管没有限制,不过官方建议采用驼峰的方式,更符合 Java 的命名约定。

3.2 Bean 名称生成器(BeanNameGenerator)

由 Spring Framework 2.0.3 引入,框架內建两种实现:

  • DefaultBeanNameGenerator:默认通用BeanNameGenerator 实现
  • AnnotationBeanNameGenerator:基于注解扫描的BeanNameGenerator 实现,起始于 Spring Framework 2.5,关联的官方文档:

4. Spring Bean 的别名

Bean 别名(Alias)的价值

  • 复用现有的 BeanDefinition
  • 更具有场景化的命名方法,比如:
<alias name="myApp-dataSource" alias="subsystemA-dataSource"/>
<alias name="myApp-dataSource" alias="subsystemB-dataSource"/>

5. 注册Spring Bean

5.1 BeanDefinition 注册

  • XML 配置元信息

    <bean name=”...” />
    
  • Java 注解配置元信息

    • @Bean
    • @Component
    • @Import
  • Java API 配置元信息

    • 命名方式:

      BeanDefinitionRegistry#registerBeanDefinition(String, BeanDefinition)
      
    • 非命名方式:

      BeanDefinitionReaderUtils#registerWithGeneratedName(AbstractBeanDefinition, BeanDefinitionRegistry)
      
    • 配置类方式:

      AnnotatedBeanDefinitionReader#register(Class...)
      

5.2 外部单例对象注册

  • Java API 配置元信息

    SingletonBeanRegistry#registerSingleton
    

6. 实例化 Spring Bean

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)

7. 初始化 Spring Bean

Bean 初始化(Initialization)

  • @PostConstruct 标注方法
  • 实现InitializingBean 接口的afterPropertiesSet() 方法
  • 自定义初始化方法
    • XML 配置:<bean init-method=”init” ... />
    • Java 注解:@Bean(initMethod=”init”)
    • Java API:AbstractBeanDefinition#setInitMethodName(String)

思考:假设以上三种方式均在同一 Bean 中定义,那么这些方法的执行顺序是怎样?

8. 延迟初始化 Spring Bean

Bean 延迟初始化(Lazy Initialization)

  • XML 配置:<bean lazy-init=”true” ... />
  • Java 注解:@Lazy(true)

思考:当某个 Bean 定义为延迟初始化,那么,Spring 容器返回的对象与非延迟的对象存在怎样的差异?

9. 销毁 Spring Bean

Bean 销毁(Destroy)

  • @PreDestroy 标注方法
  • 实现 DisposableBean 接口的 destroy() 方法
  • 自定义销毁方法
    • XML 配置:<bean destroy=”destroy” ... />
    • Java 注解:@Bean(destroy=”destroy”)
    • Java API:AbstractBeanDefinition#setDestroyMethodName(String)

思考:假设以上三种方式均在同一Bean 中定义,那么这些方法的执行顺序是怎样?

10. 垃圾回收 Spring Bean

Bean 垃圾回收(GC)

  • 关闭 Spring 容器(应用上下文)
  • 执行 GC
  • Spring Bean 覆盖的 finalize() 方法被回调

11. 面试题精选

问题1:如何注册一个 Spring Bean?

答:通过 BeanDefinition 和外部单体对象来注册。

问题2:什么是 Spring BeanDefinition?

答:回顾 "定义 Spring Bean" 和 "BeanDefinition 元信息”。

问题3:Spring 容器是怎样管理注册 Bean?

答:答案将在后续专题章节详细讨论,如:IoC 配置元信息读取和解析、依赖查找和注入以及 Bean 生命周期等。


每天用心记录一点点。内容也许不重要,但习惯很重要!

posted on 2020-02-11 21:37  binarylei  阅读(608)  评论(0编辑  收藏  举报

导航