Spring2.0中新的Bean类型实现原理

2023-10-31

  我们知道,在Spring2.0中,除了singleton及prototype两种类型的Bean以外。默认情况下还增加了request、session及global session三种类型的Bean,增加的三种类型的Bean主要应用于Web应用程序中。本文不打算分析三种类型的Bean的用法,只是简单分析框架的实现原理。
  Spring2.0中新增了一个用来表示Bean范围的Scope接口
  public interface Scope {
  Object get(String name, ObjectFactory objectFactory);//根据名称及创建工厂得到一个Bean实例
  Object remove(String name);//删除一个指定名称的Bean
  }

  在容器ConfigurableBeanFactory接口中定义了Bean工厂有关Scope注册的相关方法,使得可往Bean工厂中加入新类型的Bean。
  public interface ConfigurableBeanFactory extends HierarchicalBeanFactory,
  void registerScope(String scopeName, Scope scope);//往Bean工厂中添加一个新的范围(默认只有两种范围:singleton及prototype)
  void destroyScopedBean(String beanName);//销毁B ean工厂中范围Bean
  }

  在AbstractFactoryBean的getBean方法中实现了对特定Scope Bean支持,核心代码摘要:

    String scopeName = mergedBeanDefinition.getScope();//取得当前Bean的范围,也即在定义中的scope=”request”的部分。
    Scope scope = (Scope) this.scopes.get(scopeName);//得到Bean工厂中的范围处理器
    if (scope == null) {
     throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
    }
    try {
//使用scope.get(beanName,ObjectFactory)从指定的范围中得到或创建Bean实例
     Object scopedInstance = scope.get(beanName, new ObjectFactory() {
      public Object getObject() throws BeansException {
       beforePrototypeCreation(beanName);//前拦截
       try {
        return createBean(beanName, mergedBeanDefinition, args);//调用子类的createBean实现真正的Bean创建工作
       }
       finally {
        afterPrototypeCreation(beanName);//后拦截
       }
      }
     });
     bean = getObjectForBeanInstance(scopedInstance, name, mergedBeanDefinition);//返回正确类型的Bean实例
    }
    catch (IllegalStateException ex) {
     throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active", ex);
    }

  默认情况下,低层的Bean工厂中只支持singleton及prototype两种类型的Bean。当把scope设置成request及session时将会出现不能正确识别Scope的错误。这是因为普通的Bean工厂都没有注册新的Scope。只有在WebApplicationContext中注册才注册了新类型的Bean。
  下面看实现注册Scope的代码:
  在WebApplicationContext中定义常量
  public interface WebApplicationContext extends ApplicationContext {
  String SCOPE_REQUEST = "request";
  String SCOPE_SESSION = "session";
 String SCOPE_GLOBAL_SESSION = "globalSession";
}

  然后在所有类型的Web应用上下文的实现中,都在Bean工厂的拦载过程中通过postProcessBeanFactory方法来注册新类型Scope,如GenericWebApplicationContext、StaticWebApplicationContext、AbstractRefreshableWebApplicationContext等WebApplication应用上下文实现中。
  protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    beanFactory.registerScope(SCOPE_REQUEST, new RequestScope());//注册request类型的Bean
    beanFactory.registerScope(SCOPE_SESSION, new SessionScope(false));//注册session类型的Bean
    beanFactory.registerScope(SCOPE_GLOBAL_SESSION, new SessionScope(true));//注册glogalsession  的Bean
}

  结合上面的代码,现在应该明白为什么只有在Web应用上下文中才能使用新增加三种类型的Bean了吧。当然,由于有了Scope,我们也可以非常轻松的实现我们自己的Scope,增加新用户自定义类型的Bean,然后设计出一个适合我们自己的Bean工厂。

 

由于水平有限,文中不足之处欢迎广大Spring爱好者不吝指教,请“春迷”勿拢! 

(注:本文作者,EasyJF开源团队 大峡,转载请保留作者声明!)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring2.0中新的Bean类型实现原理 的相关文章

随机推荐

  • 版本号命名指南

    首先看看某些常见软件的版本号 Linux Kernel 0 0 1 1 0 0 2 6 32 3 0 18 若用 X Y Z 表示 则偶数 Y 表示稳定版本 奇数 Y 表示开发版本 Windows windows 98 windows 20
  • getopt_long 函数的使用

    getopt long 函数的使用网上已经有很多了 这里只是记录一下方便自己后续查找 首先函数原型声明 include
  • 情境领导者-第七章、解决绩效问题

    情境领导者 第七章 解决绩效问题 故事 总经理 并非如此 是什么意思 罗杰斯 一旦我能够使人们独立完成工作并有良好的工作业绩 而且他们能保持这个状态 那就很了不起了 总经理 这也会是你的工作变得更容易对吧 罗杰斯 的确会使我的工作变得容易些
  • ExtJs 动态添加组件

    function createComBox id name var c new Ext form ComboBox mode local forceSelection true triggerAction all displayField
  • 04模板学习之普通类继承类模板和类模板继承类模板的区别

    04模板学习之普通类继承类模板和类模板继承类模板的区别 1 普通类继承类模板 普通类继承模板时 继承的模板类必须确定类型 否则无法通过编译 因为普通类编译时需要确定基类的类型 而基类却无法确定 所以必定报错 template
  • gradle引入maven本地库中的jar包

    gradle引入maven本地库中的jar包 在build gradle中加入 def lmr file new File maven repo absolutePath repositories mavenCentral mavenLoc
  • Github上传项目报错:error: src refspec master does not match any

    想把自己在本地写好的项目上传到github 结果路途坎坷 记下历程 仅供参考 参考的第一个文档最后一步git push u origin master我却不成功 显示如下错误 于是参考网上的解决办法 把命令的最后的master改成main
  • MyBatis的XML映射文件(二)

    文章目录 动态SQL if choose trim foreach 缓存 一级缓存 二级缓存 第三方缓存 个人博客 动态SQL note 动态 SQL 是 MyBatis 的强大特性之一 如果你使用过 JDBC 或其它类似的框架 你应该能理
  • 张飞硬件设计与开发 学习笔记(第一部 线性稳压电源设计) 含理解,超详细!

    第一部 线性稳压电源的设计 前言 一 线性稳压电源的设计 1 课程概述 交流到直流降压简介 2 整流原理介绍 电阻选型 二极管介绍 3 电容的理解与选型 4 稳压电路的设计流程 5 元件详细选型 6 稳压管 三极管应用 成本控制方案二 总结
  • [获取数据集] 数据分析、机器学习获取开放的数据集

    获取数据集 数据分析 机器学习获取开放的数据集 不管数据分析还是机器学习 用真实的数据比用虚拟的数据得出的结果要好 以下是一些比较流行的开放数据存储库 里面有成千上万覆盖各个领域的数据 流行的开放数据存储库 UC Irvine Machin
  • @Cacheable使用spring缓存

    一 首先了解spring自带的注解 首先在启动类需要开启该功能 package com frame util import org mybatis spring annotation MapperScan import org spring
  • 标准c库打开创建文件读写文件光标移动

    fopen 函数 fopen只能配合使用fread fwrite等不能是read write 例子 include
  • GitHub怎样fork别人代码到自己仓库并进行贡献

    场景 比如说现在有一个很牛逼的项目 我们进入项目地址 想将这个项目复制到自己的github仓库 然后你还想将 仓库中的代码拉取到本地进行修改 修改完你还要将本地的 修改后的代码推送到自己的github仓库 更甚至你还想将自己 复制过来并修改
  • Python3数据挖掘之百度资讯搜索数据并入库(最新)

    因百度搜索页关键字内容改变 更新关键字增加正则表达式的编写 增加对批量内容爬取后的入库操作 另外需要注意学会修改正则里面变更后的内容 下面截图使用不同的颜色简单说明下 import requests import re import pym
  • Pytorch 学习(十):Pytorch 模型在 CPU 与 GPU 上的迁移

    Pytorch 模型在 CPU 与 GPU 上的迁移 本方法总结自 动手学深度学习 Pytorch版 github项目 Pytorch计算时必须保证模型和参与当前过程的所有数据都在同一个设备 GPU 或 CPU 上 CPU 与 GPU 的相
  • (附源码)springboot毕业生跟踪调查管理系统 毕业设计 061528

    springboot毕业生跟踪调查管理系统 摘 要 信息化社会内需要与之针对性的信息获取途径 但是途径的扩展基本上为人们所努力的方向 由于站在的角度存在偏差 人们经常能够获得不同类型信息 这也是技术最为难以攻克的课题 针对毕业生跟踪调查管理
  • 2月24日--3月2日(共18小时,剩4599小时)

    2月24日1小时 周日打游戏太困了 2月25日 共8小时 上午3小时DX11 下午2小时DX11 晚上3小时软引擎 2月26日 共3小时 上午2小时DX11 中午1小时软引擎 2月27日共3小时 2月28日 共3小时 3月1日 共3小时 3
  • CMAKE : INCLUDE命令

    指令 include 作用 从文件或模块加载并运行CMake代码 形式 include
  • 第一章:Linux(Ubuntu)环境下OpenCV的安装配置和实例,亲测可用

    目录 1 安装环境 1 1 安装C 开发环境 安装编译器GCC和G 1 2 安装build essential 1 3 安装cmake 1 4 安装依赖库 1 5 安装OpenCV 下载OpenCV连接OpenCV 1 6 配置环境变量 1
  • Spring2.0中新的Bean类型实现原理

    我们知道 在Spring2 0中 除了singleton及prototype两种类型的Bean以外 默认情况下还增加了request session及global session三种类型的Bean 增加的三种类型的Bean主要应用于Web应