读书人

Seam学习(10)-context变量和搜索优先级

发布时间: 2012-09-07 10:38:15 作者: rapoo

Seam学习(十)-----context变量和搜索优先级

一.Context variables(上下文变量)
上下文定义了命名空间,一组 context variables(上下文变量)。 这些工作很类似Servlet规范中对Session或Request attributes的定义。 你可以绑定任何你喜欢的值到Context Variable,但通常我们会绑定Seam组件实例到Context Variables。

因此,在上下文中,组件实例是通过上下文变量名字来辨别的(通常是这样,但并非绝对,就和组件名称一样)。 你可以通过程序在特定范围内访问被命名的组件实例,这是通过 Contexts 类进行的,它提供了对 Context 接口的几个线程绑定的实例的访问:

User user = (User) Contexts.getSessionContext().get("user");
你也可以通过名字来设置或修改变量值:

Contexts.getSessionContext().set("user", user);
但通常,我们通过注射(injection)来从上下文中获得组件,并且通过反向注射(outjection)把组件实例返回上下文。

二.Context搜索优先级
有时候如上面的例子所示,组件实例是从某个特定的已知范围内获取的。 其他的时候则是通过 priority order(优先级顺序) 在所有有状态范围内搜寻。这个顺序是这样的:

Event context

Page context

Conversation context

Session context

Business process context

Application context

你可以通过调用 Contexts.lookupInStatefulContexts() 来执行带优先级的搜索。你在JSF页面中通过名字访问组件的时候,执行的就是这种带优先级的搜索。

并发模型
Servlet和EJB规范都没有定义任何关于如何管理来自同一个客户端的并发请求的条款。 Servlet容器简单地让所有的线程并发运行,把线程资源安全共享的任务交给应用程序代码。 EJB容器允许无状态组件并发访问,但如果并发访问一个有状态Session Bean,就会抛出一个异常。

旧式的Web应用程序是围绕细粒度的同步请求编写的,因此这种行为可能还OK。 但是对现代的程序而言,由于大量使用了很多细粒度的异步(AJAX)请求,并发是实际存在的,并且必须被程序模型支持。 Seam在其上下文模型中加入了并发管理层。

Seam Session 和应用上下文是多线程的。Seam允许在一个上下文中并发请求,并发处理。事件(Event)和页面(Page)上下文自然是单线程的。 业务流程(business process)上下文严格而言是多线程的,但实际情况中并发很少见,因此大多数情况不会出现并发。 最后,Seam为Conversation Context提供了 每对话每进程单线程 模型,这是通过把同一个长时间运行的对话上下文中的并发请求序列化实现的。

因为Session上下文是多线程的,并且经常包含不稳定的状态,所以Session范围内的组件总是被Seam保护以防止并发操作。 Seam默认把针对Session范围的Session Bean和JavaBean的请求序列化(并且检测、解决任何发生的死锁)。 对Application Scoped的组件来说,这却不是默认行为,因为Application Scoped的组件通常不会包含的不稳定状态,并且在全局级别进行同步代价 极其 高昂。但是,你可以强制对任何Session Bean或JavaBean组件采用序列化的线程模型,要做的就是加上 @Synchronized 注解。

并发模型意味着AJAX客户端可以安全的使用不稳定的Session和会话状态,并且不需要开发者做任何特别的工作。

读书人网 >软件架构设计

热点推荐