赛迪网 > IT技术 Java > 技术动态
  IT资讯搜索
 
IT产品搜索
[程序开发][网管世界][网络安全][数据库技术]
[操作系统][嘉宾聊天·在线访谈][活动集锦]
[精彩专题][Symantec专区][订阅IT技术周刊]
[开发论坛][网管论坛][安全论坛][数据库论坛]
[操作系统论坛][Sybase专区][IBM dW技术专区]
[病毒求助][病毒与漏洞播报][文档·源码下载]

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

发布时间:2008.01.10 04:53     来源:赛迪网    作者:easyjf

我们知道,在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工厂。
         (责任编辑:包春林)


[ 发表评论 ] 字体[  ] [ 打印 ] [ 进入博客 ] [ 进入论坛 ]  [ 推荐给朋友 ]
  相关文章
· J2SE综合--Apache Commons工具集简介 (01-09) · Java入门--深入讨论JAVA规则开发篇 (01-09)
· 基础:int 和 String 互相转换的多种方法 (01-09) · J2EE综合:谈谈Java Web开发的学习路径 (01-09)
· Java 5.0的垃圾收集 (01-09) · 浅析设计模式中的Iterator迭代器 (01-09)
· 设计模式之Proxy (01-08) · 通过Struts应用MVC设计模型 (01-08)
· 设计模式之Bridge (01-08)
  客户需求反馈表
* 姓  名:
更多资料  了解方案  认识厂商
* 单位名称:
* 联系电话:
* 电子邮件:
  赛迪推荐  
  手机·资费 ·新品·导购·评测·手机资费·宽带
手机搜索  诺基亚 N73 MOTO Z6
  IT产品 ·笔记本·台式机·服务器·打印·投影
IT产品搜索 
  IT技术 ·开发·网管·安全·数据库·操作系统
  信息化 ·热点·专题·访谈·周刊·方案案例
· 网银交易收费 我国银行业如何达国际化标准
· 家庭信息化普及率提高 网上缴费成为新时尚
· 五条黄金准则能够让CIO巧妙加薪 CIO焦虑调查
· 网上书店解决方案 深圳边检指挥中心ITSM项目
  IT博客 ·曾剑秋·项立刚·Java学习·网管
  IT技术论坛 ·开发·网管·安全·数据库·系统