20150706 Created By BaoXinjian


架构概述

下图显示了基本的OAF状态管理组件的应用开发视图(它并没有反映所有的OAF细节)。


在OAF页面中,每个页面都关联到一个root application module,提供了事务上下文和JDBC数据库连接(在OAF中,数据库会话是关联到JDBC连接的)。

Root application module是OAF的中枢module,因为核心的应用数据(视图对象、实体对象等)和页面的WEB BEAN结构都自动被它(oracle.apps.fnd.framework.OADBTransaction)缓存。

警告:使用后退按钮可能使APPLICATION MODULE状态丢失。在编写代码之前请参考“支持后退按钮”。

所有存在于事务中的数据对于所有共享这一ROOT APPLICATION MODULE实例的页面都是可访问的。

OAF提供了你可以用来从事务中存储、取出、删除数据的方法。一个简单的事务可以被控制器和模型中的代码访问,这些工具是在oracle.apps.fnd.framework.webui.OAPageContext(对于控制器)和OADBTransaction(对于模型)中提供的。

1. 保持ROOT APPLICATION MODULE

默认情况下,当用户从一个页面转到另一个页面时(如一个GET请求或者一个JSP FORWARD),OAF生成一个新页面,前一个页面的application module被释放,一个新的实例从applicaiotn module池中生成。

注意:OAF从不会释放从POST请求提交的application module(除非你手工释放)。如:如果用户对一个表格排序或在表格间跳转(两个在后台提交form的动作)页面的application module实例自动被保持。

2. 保持页面间的APPLICATION MODULE

上面所说的情况适合于单独的、完整的任务。但对于由多页面组成的一个任务或者多个关联页面共用一个事务的情况,不同的页面就必须关联到一个ROOT APPLICATION实例。

达到以上的情况,你必须做到:

(1).  在多页面中为每个页面指定同一个root application module。

(2). 通过指定URL参数retainAM=Y来设置application module retention标记。

对于GET请求,这个标记是在新页面显示的时候被处理的(如上面所提到的,OAF总是为POST请求保持同一个application module,而不管retainAM参数)。

如果设为Y,前一个页面的application module会被保留,如果设为N(或者不设,视同为N),OAF会释放所有的application module,包括以前那些显式声明为保留的

你也可以在JSP FORWARD 的OAPageContext时设置此参数。

警告:只在不同的页面关联同一个root application module是不够的。如果你忘了设置retainAM标志,每个页面会使用不同的application module实例和事务,即使它们关联到了同一个application module 类型。

注意:典型情况下,根据application module池的状态,页面B 不能得到物理上的页面A的application module。但是,对象的状态会完全重置就像建立一个新的一样。你可以认为他是一个新的实例。

同样的,如果你设置了retainAM标志为Y,但是没有将多个页面关联到同一个application module,你的多个页面也会使用不同的application module和事务。

3. 有条件的保留/释放application module

在一些情况下,你可能需要决定是否要保留或释放一个application module。

你可以为不同的application module实现oracle.apps.fnd.framework.webui.OAReleaseListener接口。

警告:开发团队没有得到提醒之前,不应该使用这个接口。不正确的使用这个接口会导致内存泄漏。

4. 显式释放application moudule

有时你也会想显式的释放一个root application module,特别地,你在页面控制器中调用OAPageContext.releaseApplicationModule()方法,

OAF将会一完成页面显示就释放页面的root application module,而不用等待下一个application module请求。


下表描述了applicatoin module保留或释放的建议


如果在JSP基础中提到的,一个servlet session是在一系列HTTP请求的连续动作过程中在浏览器和服务器之间保持状态的的机制。

一个session可能在任意时候被应用服务器建立或通过应用、用户关闭浏览器、用户超时来终止。一个session通常对应于一个登录/退出过程,但是在OAF中并不是完全这样。

你可以在servlet session中缓存一个小的可保存的对象(OAF中必须是字符串、数字、日期),同一个session中任何页面都可以访问缓存中的数据。如:如果你认为从数据库中读取用户信息太耗资源了,你可以使用这个方法

注意:只有当你需要在不同root application module的多个页面中访问一个简单值的时候才需要使用session缓存。

你必须记住servlet session数据是没有被清除的(当SESSION激活的时候)必须被显示的清除。这样的话,如果用户没有退出而是简单的中止了,因为没有更好的事件来释放内存,故session是最后一个选择。

提示:有经验的JSP开发者可以会疑惑为什么不用隐藏域,根据OAF当前的菜单实现方法(一些菜单发送GET请求而不是POST请求),所以当你选择一个菜单里,不可能总是向请求中添加值。

如果要在SERVLET SESSION中存储、接收、删除值,查看OAPageContext put*(),get*()和remove8()方法。


当用户登录到OAF中时,OAF建立一个AOL/J oracle.apps.fnd.common.WebAppsContext对象和基于SESSION的cookie,一起保持应用的上下文信息,如当前职责、组织ID和用户信息等。

1. Cookie保存了session中的加密的关键信息,这是数据库中的一行数据(特别的,这是一个servlet session id,在已解密的form中,是在ICX_SESSIONS表中的主键)

2. WebAppsContext从每个请求中接收键值,使用它来查询当前的session状态。

3. 用户session关联到一个servlet session,但它有自己的生命周期和超时特性。

(1). 一般情况下,用户session应该比servlet session生命周期更长。

(2). 一个用户session可能关联到多个servlet session(如果,如:当用户在建立一个时间很长的报表过程中,servlet session超时了,然后还可以在用户session超时之前继续工作)。

(3). 一个servlet session可能关联到多个用户session(如:一个用户退出,没有关闭窗口又后退)。

4. 如果用户session超时了,用户也没有关闭浏览器窗口(基于session的cookie也没丢失),也没有人删除ICX_SESSIONS表的对应记录,用户就可以在登录后从上次停止的地方继续工作。

如果你需要访问用户session中的数据,你可以OAPageContext(在控制器代码中)或者OADBTransaction(在模型代码中)。


当不能访问OAPageContext时,你也可以使用应用上下文来存储状态(在JAVA 服务器层或者PLSQL代码中)。这样的话,你可以使用WebAppsContext.setSessionArribute(name,value)方法。


每次接收到一个页面的请求,OAF都建立一个OAPageContext存储信息,直到新的页面完成(特别的,OAPageBean建立OAPageContext,它主要是在页面后台起做作)


一个WEB应用的工作单元是一对请求/响应,浏览器发送请求,servlet处理这个请求并返回一个响应,响应的传送意味着一个请求的结束,或者是一个请求的完成与新的请求之前的分界。

同样,当OAPageBean完成页面的处理,这也是当前页面与新页面之间的分界。

所以,一个用户从页面X跳转到页面A,又跳转到页面B,这时我们有两个请求边界:X和A之间,A和B之间。也有两个页面边界:X和A,A和B。

有些情况下,请求和页面的边界不相同,考虑以下情况:

用户从X到A

在A的时候,在响应决定显示哪个页面之前,用户选择了A的控件,所以,浏览器发送了一个请求到A,当A处理结束,就达了第一个页的边界。

在页面A的代码中,开发者估算用户选择了哪个控件发送JSP FORWARD到页面B,因为我们不想重新显示A,所以不用反回HTTP响应,OAF开始处理页面B(包括建立一个新的OAPageContext),一旦B处理完成,就到达了第二个页面边界。

因为页面B必须显示给用户,故一个HTTP响应发送到浏览器,就到了请求的边界。

基于以下的原因,明白这一点是很重要的

1. 请求参数存在于请求的生命周期中,它可以跨越多个页面的边界。这对于那些认为一个请求和一个页面相同的开发者来说有点奇怪,在JSP FORWARD后也不用说明请求参数还存在。如以下示例:

(1). 用户选择了页面X中的连接,转到页面A,页面A的URL包括参数foo=bar

(2). 页面A发送一个到页面B的JSP FORWARD,现在即使我们是在一个新的页面中,请求中仍然包括foo=bar

(3).  如果你不想在jsp forward后还包括参数,你必须显式的覆盖它(注意你不能从请求中删除参数),如当你调用OAPageContext的setForward方法时你可以重置参数,foo=X

提示:将不需要的参数设为一个新值更可取,不要简单地将它设为“”。

2. 因为在页面上下文与请之前没有一对一的关系,对于从OAPageContext中访问请求参数,有人会感到疑惑。只要记得每个页面是一个明确的实体,从它的“显示点”OAPageContext表示了一个请求。

3. 当你进入上图的细节时,你会看到页面与请求的边界是明确的有不同含义的钝化事件点。


尽管是生命周期很短,每个HTTP请求还是建立一个对象。这个对象包括以下应用状态:

所有的URL参数,不管是POST还是GET。

如果是POST请求,包括FORM中的数据。

如果是POST请求,web bean和事件名称会关联到用户选择的控件(如用户选择了一个GO按钮,请求会包括以这个按钮命名的web bean,所以你可以知道它被按下了并以此做出响应)。

为了访问请求值,使用OAPageContext的getParameter*()方法。


一个隐藏域是开发者在FORM中读取或写入数据工具,它不能被用户访问。如同用户看到的FORM域一样,隐藏域也在提交时被加到了请求中。

你可以通过在Jdeveoper中选择item style的formValue建立一个隐藏域。在运行时,它以oracle.apps.fnd.framework.webui.beans.form.OAFormValueBean来初始化。


当你显式的使用OAPageContext setForward*()或者OAPageContext.sendRedirct()方法转到一个新的页面时,你可以设定请求参数。

例如:假定有一个页面包括一个提交按钮,当用户点击时,我们想使用JSP FORWARD转到B页面。页面A需要一传递一个mode值给页面B(可以由不同的方式来访问),所以它知道如何做

1. 用户点击提交按钮。

2. 在页面A的控制器中处理这个按钮,在processFormRequest方法中调用OAPageContext.setForwardURL()。做为一个方法调用,设定参数queryMode=automatic。

3. 在页面B的控制器中,在processRequest方法中检查参数queryMode值,调用getParameter(“queryMode”)。

4. 页面B控制器于是响应queryMode参数值为automatic,查询数据来显示页面。

调用OAPageContext.putParameter()指定值


OAPageContext包括putParameter()方法,在页面处理过程中,你可以用来传递值到web bean结构中,或者使用jsp forward从一个页面传到下一个页面。

如:一个顶层的region可能放置一个值到缓存中,它的子region可以引用。

提示:这个和JAVA SERVLET 2.1的HttpServletRequest.setAttibute()方法很相似,可以认为它们做用相同。


当在Jdeveloper中定义URL时你可以指定请求参数,或者在相关的程序中设置URL。

警告:URL是有长度限制的,你应该小心的添加URL参数的数量,尤其是很长的时候。因为URL是可见的,你应该加密敏感的值,然后再解密。


OAF是事务导向的,许多事务都跨越了多个页面。这些事务需要一定的状态来保存信息直到用户完成任务。如:一个建立采购定单的的流程中,用户在第一页描述定单,在第二页输入一个或多个项目,在第三页提交前检查信息,这个采购定单数据在每个浏览器提交的请求之间必须被保存。

HTTP协议是无状态的,它不能保存任何指定的状态也不保证支持状态保存。而且,如果提供servlet session的JVM实例失败了,或者servlet session超时了,应用状态就丢失了,等待的事务也不能恢复。

OAF,从另一方面来讲,当用户工作时,合并了保存与恢复客户端状态的能力,即使是servlet session超时(以后的版本会提供JVM失败的支持)。

1. 保存应用状态到另一个地方(在OAF中,是保存在数据库中)叫做钝化。

2. 从其它地方恢复应用状态叫做活化。

特别的,OAF目前提供了以下的状态管理特点:

可变的应用,当资源消耗很高时,OAF保存空闲线程的状态,并将它们的资源重新分配给其它线程,而不是新建一个资源实例。当空闲的线程激活时,保存的状态被恢复。简单说,资源会在JDBC连接、application modules、用户session中重新分配。

Servlet session 超时恢复,servlet session会超时,而不用用户重新开始一个未完成的事务(将来这个特点会扩展到提供中间层的失败支持)。


为了提高性能和可变性,OAF缓冲了APPLICATION MODULE,重用是比重建更有效的方式。在简单的情况下:

1. 每个JVM都有一个application module池管理器,里面包含和管理不同的application module池。

2. 每个application module池包含了一些application module的实例,

如,如果一个应用使用了两个root application module,就有两个application module池:

oracle.apps.fnd.framework.toolbox.tutorial.server.Lession3AM和oracle.apps.fnd.framework.toolbox.tutorial.server.Lession4AM,

如下图。换句话说,每个root application module都建立一个池。

3. 在池中的application module实例被设计成可用的或者不可用的(当前被提取走的)。

4. 只有root application module是放在池中的,嵌套的application module是被root application module缓冲的。

Thanks and Regards

参考:红豆加奶 - http://shaofeng.blog.51cto.com/3392077/655672

OAF_OAF Framework状态分析(概念)的更多相关文章

  1. OAF_OAF Framework学习笔记的基本概念(概念)

    2014-11-02 Created By BaoXinjian

  2. OAF_OAF Framework页面分析(概念)

    20150506 Created By BaoXinjian

  3. OAF_OAF Framework常用函数汇总(概念)

    2014-12-31 Created By BaoXinjian

  4. .NET Framework基本概念

    http://blog.csdn.net/T573029173/article/details/41730101 .NET是微软的新一代技术平台.对技术人员来说,想真正了解什么是.NET,须先了解.N ...

  5. Entity Framework 基本概念

    概念 LINQ to Entities 一种 LINQ 技术,使开发人员可以使用 LINQ 表达式和 LINQ 标准查询运算符,针对实体数据模型 (EDM) 对象上下文创建灵活的强类型化查询. ESQ ...

  6. 关于Entity Framework的概念及搭建

    什么是EF? ADO.NET Entity Framework 是一个对象-关系的映射架构. 它支持直接定义完全独立于数据库结构的实体类,并把它们映射到数据库的表和关系上. 三种编程模型: 数据库优先 ...

  7. Spring Framework核心概念之Bean生命周期管理

    目录 Spring Bean的生命周期 相关接口的分类 测试SpringBean生命周期的Demo程序 小结 Spring Bean的生命周期 Spring容器既Application或者WebApp ...

  8. ADF_ADF Framework基本概念(概念)

    2014-01-01 Created By BaoXinjian

  9. 在iOS开发中,给项目添加新的.framework

    首先需要了解一下iOS中静态库和动态库.framework的概念 静态库与动态库的区别 首先来看什么是库,库(Library)说白了就是一段编译好的二进制代码,加上头文件就可以供别人使用. 什么时候我 ...

随机推荐

  1. 关于一道JS面试题的思考

    题目: ; i < ; i++) { setTimeout(function() { console.log(new Date, i); }, ); } console.log(new Date ...

  2. Android Notification实现推送消息过程中接受到消息端有声音及震动及亮屏提示

    在Android Notification状态栏通知一文中,简单实现了消息的推送效果,这里就接着上文说一下,当用户接受到消息时的提示效果 // 5-增加震动及声音及亮屏 notification.de ...

  3. URAL 1698

    题目大意:统计位数不大于n的自守数的个数. KB     64bit IO Format:%I64d & %I64u 数据规模:1<=n<=2000. 理论基础: 自守数:参见链接 ...

  4. window系统下调度数据库类型资源库中的kettle job

    已经存在kettle的一个资源库enfo,在目录/works/wxj下面有一个job (testmailsuccess.kjb)如何实现手工在kettle外部执行此job和让系统每天定时的调用此job ...

  5. [Functional Programming 101] runWIth, evalWith, execWith

    Recentlly, I am learning crocks.js ADT libaray. In the beginning, it is hard to understand when to u ...

  6. Missing styles. Is the correct theme chosen for this layout? Use the Theme combo box above the layou

    android无法静态显示ui效果. Missing styles. Is the correct theme chosen for this layout? Use the Theme combo ...

  7. 如何自定义CollectionView中每个元素的大小和间距

    问题: 让每个元素大小变为104 x 104 Step 1: 在你的视图控制器头文件中实现UICollectionViewFlowLayout协议 eg: @interface XXViewContr ...

  8. poj 2391 (Floyd+最大流+二分)

    题意:有n块草地,一些奶牛在草地上吃草,草地间有m条路,一些草地上有避雨点,每个避雨点能容纳的奶牛是有限的,给出通过每条路的时间,问最少需要多少时间能让所有奶牛进入一个避雨点. 两个避雨点间可以相互到 ...

  9. Java的类名与文件名必须一致(转)

    原文:http://blog.csdn.net/shaoxiaoning/article/details/40424087 1.Java保存的文件名必须与类名一致: 2.如果文件中只有一个类,文件名必 ...

  10. cocos2d 重写顶点着色语言

    bool CCShaderSprite::initWithFile( const char *pszFilename ) {  bool ret=false;  do  {    ret=CCSpri ...