ColdFusion Application.cfC语言 执行顺序



我需要现实检查 - 并希望得到解释(如果我的现实是错误的)。

CF应用程序框架评估事物的方式是这样的(我的理解)- 请求被传递给 cfserver

  • CF 查找应用程序.cfm或 CFC(基于遍历规则)

  • application.cfc 执行(如果找到)

  • 设置了 THIS 作用域(可以在此处设置一系列特定于应用程序的变量,但

一些是必需的 - 例如"applicationTimeout" - 然后发生一系列事件 - 并在需要时触发方法。

-- onApplicationStart()

----在会话开始()

------onRequestStart()

等。

所以我的问题

1) THIS 设置发生在每个页面请求上 - 先于其他任何事情?

2)如果我设置了一个应用程序变量,在onApplicationStart() - 它在那之后发生的任何进程中都可用 - 并且应该在applicationTimeout()的长度内保留在内存中 - 对吗?

3)所以如果我做这样的事情...

if ( isdefined("application.myvar" ) { this.something = application.myvar; }

它应该在启动应用程序范围的初始请求之后处理任何页面请求。

但是它似乎没有这样做。

我问的原因是 - 需要在 THIS 范围内设置一些有趣的应用程序杠杆设置......其中一些可能是"密集的"(至少形成了执行每个请求的观点 - 所以我只想做一次,在持久 mem 中设置一个结构,然后将它们作为 THIS。

我是否做出了一些错误的假设?

感谢

ColdFusion Application.cfc 文档包含以下知识:

当请求执行时,ColdFusion 会在 以下顺序:

  1. onApplicationStart (如果之前未为此应用程序运行)
  2. onSessionStart (如果之前未为此会话运行)
  3. onRequestStart
  4. onRequest/onCFCRequest
  5. onRequestEnd

onApplicationEnd、onSessionEnd 和 onError CFC 由特定事件触发。

整个请求顺序(至少)还有两个步骤。

0:执行cfcomponent中不在cffunction
中的所有代码 0.5:运行等效的 cfapplication 标记来创建应用程序

因此,您的问题的答案是:

  1. 如果您在步骤 0 中设置这些变量,那么是的。
  2. 正确。
  3. 这取决于您设置变量的位置。 如果您尝试更改的值列在 Application.cfc 的"应用程序变量文档"页上,则它们必须位于步骤 0 中。 将它们设置在其他地方将更新this范围,但不会在步骤 0.5 中生效。

这里有两件事在起作用:代码何时运行,何时使用变量作用域以及它们持续多长时间。

  • 代码输出与任何方法(即:"伪构造函数")运行每个请求。 显然,最大限度地减少了 CFC 这一部分中的代码量。
  • 各种事件处理程序
  • 中的代码按照事件处理程序名称的指示运行,例如:onApplicationStart() 代码仅在应用程序启动时运行一次。 同上,onSessionStart() 每个新会话只运行一次。

范围:

  • 整个氟氯化碳都有这个范围。 行为与任何其他 CFC 中的 this 作用域完全相同,除了一些 this 作用域变量具有特殊含义(如 this.namethis.datasource 等)。 这些特殊含义的变量可以在相关处理程序中按会话或每个请求更改,但似乎适用于整个系统(即:不适用于进行设置更改的特定会话或请求)。 在普通 CFC 中,this 作用域用于公开公共变量,但由于没有 Application.cfc 的公共实例,因此除了进行这些特殊设置之外,使用 this 作用域没有任何意义。 如果希望变量可用于 CFC 中的所有方法,请像往常一样使用变量范围。 与此处某人的建议相反,此范围的变量与应用程序范围的变量不同。
  • 请求范围也在整个 CFC(伪构造函数和方法)中可用。 这些也将可用于请求稍后调用的模板的调用代码,就像任何其他请求范围的变量一样。
  • 应用程序范围:在伪构造函数中不可用,即使在进行this.name设置后也是如此。 仅在 onApplicationStart() 中可用,此后从那里开始。
    • 会话范围:同样,在伪构造函数或 onApplicationStart()l 中不可用,直到 onSessionStart() 才可用。

我已经在博客文章(提供测试代码)中演示了这一点。 它太长了,无法包括在这里,但上面的东西总结了它。

请参阅评论,因为下面的帖子似乎有效,但事实并非如此。 如果转储此作用域,则会显示新值,但实际上不会更改任何应用程序设置。

您可以在任何您喜欢的位置更改任何应用程序设置;但是,由于每次请求页面时都会运行伪构造函数,因此您需要在伪构造函数运行后不断更改设置。 应用程序范围在伪构造函数中不可用,因此您可以在 onRequestStart 或 onRequest 函数中执行此操作。我已经做了一个简单的测试,根据onRequestStart函数中的条件重新分配自定义标记路径。您会注意到第一次访问页面时,自定义标签文件夹将是"自定义标签",其他请求将指示"someOtherCustomtagsFolder" 附带说明一下,如果您的应用程序设置按用户更改,您的全局应用程序设置将翻转,并可能导致其他用户获得不正确的设置。

<cfcomponent>
<!--- pseudo constructor --->
<cfset this.customtagpaths = expandPath('./customtags')>
<!--- onRequestStart --->
<cffunction name = "onRequestStart" returnType="void">
     <cfif structKeyExists(application,'testSetting')>
          <cfset this.customtagpaths = expandPath('./someOtherCustomtagsFolder')>
     </cfif>
</cffunction>
<!--- onRequest --->
<cffunction name = "onRequest" returntype="void">
     <cfargument name="targetPage" type="String" required = "true" />
     <cfdump var = "#this#" label = "this">
     <cfset application.testSetting = "foo">
     <cfinclude template="#Arguments.targetPage#">
</cffunction>
</cfcomponent>

Application.cfc 文件内范围内的任何内容都将成为应用程序变体,并且每个应用程序生命周期仅创建一次。应用程序启动后,Application.cfc 中没有其他用户。

第一次运行 CF 应用程序时,onApplicationStart() 的内容在 onRequest/Start/End 之前运行(除了 "new in CF10" onServerStart())。

在应用程序停止之前,在应用程序中任何位置设置的任何应用程序变量都存在。

来自 #3 的代码应该只是

if ( !structKeyExists( application, "myvar" ) { application.myvar = foo; }

然后在您需要的地方引用 application.myvar。

从您的描述来看,不需要在此范围内添加任何内容,只需将其放入应用程序范围即可。

应用程序范围在 Application.cfc 伪构造函数中不可用,因为在设置 this.name 之前,无法将请求绑定到应用程序。

如果您担心创建应用程序映射的开销,一种方法是将它们缓存在可用的服务器作用域中。

if(!structkeyexists(server, 'myappmappings')){ server.myappmappings = createMappings();}this.mappings = server.myappmappings;

你也可以使用 cachePut/cache Get 将映射存储在 ehcache 中,但我还没有在伪构造函数中尝试过。

最新更新