【Spring编程思想】二、Spring Bean 基础

Spring 基础

本节代码示例:spring-bean 模板

一、定义Spring Bean

  • 什么是BeanDefinition?

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

      • Bean 的 类名

      • Bean 行为配置、如作用域、自动绑定的模式,生命周期回调等

      • 其他Bean引用,又可称合作者(collaborators) 或者依赖 (dependencies)

      • 配置设置。 如:Bean属性(Properties)

二、 BeanDefinition 元信息

属性(Property)说明
ClassBean 全类名,必须是具体类,不能用抽象类或接口
NameBean的全称或ID(识别符)
ScopeBean的作用域(如:singleton、prototype等)
Constructor argumentsBean构造器参数(用于依赖注入)
PropertiesBean属性设置(用于依赖注入)
Autowriting modeBean自动绑定模式(如:通过名称byName,类型byType)
Lazy initialzation modeBean延迟初始化模式(延迟和非延迟)
initialzation modeBean回调方法名称
Destruction methodBean销毁回调方法名称

代码演示参考: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的配置元信息

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值