我需要一个现实检查 - 希望解释(如果我的现实是错误的)。
在CF应用程序框架评估事情的方式是这样的(我的理解) - 请求传递给cfserver
有些是必需的 - 如“applicationTimeout” - 那么一系列事件的发生-and如果需要解雇的方法。
- onApplicationStart()
---- onSessionStart()
------ onRequestStart()
等等
所以我的问题
1)本设置发生在每一个页面请求 - 先天下之忧?
2)如果我设置应用程序变量,在onApplicationStart() - 它是在之后发生的所有过程中可用 - 并在内存中应该坚持applicationTimeout()的长度 - 正确的?
3),所以如果我做这样的事情?
如果(isdefined( “application.myvar”){this.something = application.myvar;}
它应该在启动应用程序范围的初始请求之后的任何页面请求工作。
但它似乎并没有这样做。
我之所以要求是这样的 - 有需要在此范围内要设置一些有趣的应用杠杆设置...他们几个可能是“密集”(至少形成执行上的每个请求的角度看 - 所以我想做他们只有一次,请在执着MEM的结构,然后有那些可以作为这一点。
我在做一些错误的假设?
谢谢
该ColdFusion的文档的Application.cfc有知识的这么一个小节目:
当请求执行,ColdFusion的运行在下面的顺序CFC方法:
- onApplicationStart(如果不是因为这个应用程序之前运行)
- onSessionStart(如果不是本次会议之前运行)
- onRequestStart
- onRequest / onCFCRequest
- onRequestEnd
该onApplicationEnd,onSessionEnd和onError的含氯氟烃由特定事件触发。
整体请求顺序具有(至少)两个步骤。
0:执行中的所有代码cfcomponent
不在一个cffunction
0.5:运行的等效cfapplication
标签创建Application
这样的问题的答案是:
- 如果你在步骤0设置这些变量,那么是的。
- 正确。
- 这取决于你在哪里设置变量。 如果你正在试图改变这些值的上市申请文件的变量为的Application.cfc页那么他们必须在0步设置它们放在别的地方会更新
this
范围,但不会采取步骤0.5的效果。
有在剧中的两件事情在这里:代码运行时,当变量的作用域可提,他们持续多长时间。
- outwith任何方法中的代码(即:“pseudoconstructor”)运行的每个请求。 显然最小化在CFC的这一部分的代码量。
- 在不同的事件处理程序代码运行的事件处理程序的名称标识,如:onApplicationStart()的代码只运行一次,应用程序启动时。 同上onSessionStart()只运行每个新的会话一次。
作用域:
- 这个范围遍及CFC可用。 行为完全像任何其他CFC的这个范围的,除了一些这个范围的变量具有特殊意义(如
this.name
, this.datasource
等)。 这些特殊的意义变量可以针对每个会话或每个请求的相关处理程序被改变,但是似乎适用于整个系统(即:不是为特定的会话或请求作出设置改变)。 在正常的氟氯化碳,在this
范围用于暴露公共变量,但由于存在的Application.cfc没有公共实例,存在使用不点this
范围以外使这些特殊的设置。 如果想要有提供给CFC中的所有方法变量,使用变量的作用域为一个通常会。 相反,这里的人的意见,这个范围的变量是不一样的应用程序范围的变量。 - 请求范围也可在整个CFC(伪构造函数和方法)。 这些也将提供给后面的请求来调用模板调用代码,像任何其他请求范围的变量。
- 应用范围:在伪构造函数不可用,即使
this.name
设置完成。 只有成为onApplicationStart可用()和此后来自那里。 - 会话范围:类似地,不是在伪构造或onApplicationStart()升可用,直到onSessionStart()。
我已经在博客中表明了这一点(测试代码提供), 在这里 。 它太冗长,包括在这里,但上面的东西概括它。
请参阅评论,因为它会出现在后下工作,但事实并非如此。 如果您转储此范围,则显示你的新的价值,但它实际上并没有改变任何应用程序设置。
您可以更改任何应用程序设置任何你喜欢的; 然而,由于伪构造函数在每次请求页面时运行,你需要伪构造函数运行后不断更改设置。 应用范围不是伪构造函数可用,因此您可以在onRequestStart或onRequest功能做到这一点。 我做了一个简单的测试重新分配每状态customtagpaths在onRequestStart功能。 你会在第一时间通知您访问的页面的自定义标签的文件夹会“customtags”额外的请求将显示“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文件中变为应用程序varialbe并且只每个应用程序的生命周期产生一次。 在应用程序启动后,有内的Application.cfc没有其他用户这一点 。
第一次一个CF应用程序运行时,onApplicationStart的()中的内容onRequest /开始/结束之前运行(与“新的CF10” onServerStart除外())。
在应用程序中的任何位置设置任何应用程序变量的存在,直到应用程序停止。
从#3你的代码应该只是
if ( !structKeyExists( application, "myvar" ) { application.myvar = foo; }
然后引用application.myvar无论你需要它。
从你的描述,没有什么需要添加到这个范围,它只是需要被放置在应用范围。
应用范围不在的Application.cfc伪构造函数可用,因为直到this.name已定没有办法扳平请求应用程序。
如果你担心创建的应用程序映射的开销,一种方法是缓存他们在服务器范围内是可用的。
如果{server.myappmappings = createMappings()(structkeyexists(服务器, 'myappmappings')!); } this.mappings = server.myappmappings; } this.mappings = server.myappmappings;
您可能还可以使用cachePut /缓存获取到的映射存储的Ehcache,但我还没有尝试在伪构造函数。