ColdFusion Application.cfc - порядок исполнения
Мне нужна проверка реальности - и, надеюсь, объяснение (если моя реальность не так).
Среда приложения CF оценивает вещи так (мое понимание) - запрос передается в cfserver
cf находит application.cfm или cfc (на основе правил обхода)
application.cfc выполняется (если найден)
НАСТОЯЩАЯ область действия (здесь можно установить серию переменных для конкретного приложения, но
некоторые требуются - например, "applicationTimeout" - тогда происходит ряд событий - и методы запускаются при необходимости.
- onApplicationStart ()
---- onSessionStart ()
------ onRequestStart ()
и т.п.
так что мои вопросы
1) НАСТОЯЩИЕ настройки происходят по КАЖДОМУ запросу страницы - прежде всего?
2) Если я устанавливаю переменную приложения, в onApplicationStart() - она доступна в любом процессе, который происходит после этого - И должна сохраняться в памяти для длины applicationTimeout() - правильно?
3) так что если я сделаю что-то подобное...
if (isdefined ("application.myvar") {this.something = application.myvar;}
он ДОЛЖЕН работать на любом запросе страницы после первоначального запроса, который запустил область приложения.
Однако, похоже, это не так.
я спрашиваю, вот почему - есть некоторые интересные настройки рычага приложения, которые должны быть установлены в ЭТОЙ области видимости... некоторые из них могут быть "интенсивными" (по крайней мере, с точки зрения выполнения по КАЖДОМУ запросу - поэтому я хочу чтобы сделать их только ОДИН РАЗ, установите структуру в постоянном mem, и затем сделайте так, чтобы они были доступны как ЭТО.
я делаю неправильные предположения?
Спасибо
5 ответов
Документация ColdFusion Application.cfc обладает следующими знаниями:
Когда запрос выполняется, ColdFusion запускает методы CFC в следующем порядке:
- onApplicationStart (если не запускалось раньше для этого приложения)
- onSessionStart (если не запускалось раньше для этого сеанса)
- onRequestStart
- onRequest / onCFCRequest
- onRequestEnd
CFC onApplicationEnd, onSessionEnd и onError запускаются определенными событиями.
Общий порядок запроса имеет (как минимум) еще два шага.
0: выполнить весь код в
cfcomponent
это не вcffunction
0.5: запустить эквивалентcfapplication
тег для создания приложения
Ответы на ваши вопросы таковы:
- Если вы устанавливаете эти переменные в шаге 0, тогда да.
- Правильный.
- Это зависит от того, где вы устанавливаете переменную. Если значения, которые вы пытаетесь изменить, перечислены на странице документации по переменным приложения для Application.cfc, то они должны быть на шаге 0. Установка их в другом месте приведет к обновлению
this
область действия, но не вступит в силу на шаге 0.5.
Здесь есть две вещи: когда выполняется код и когда доступны переменные области и как долго они работают.
- Код вне любого метода (то есть: "псевдоконструктор") выполняет каждый запрос. Очевидно, минимизировать количество кода в этой части CFC.
- Код в различных обработчиках событий выполняется, как указано в имени обработчика событий, например: код onApplicationStart() выполняется только один раз, когда запускается приложение. То же самое onSessionStart() запускается только один раз за новый сеанс.
Области применения:
- эта сфера доступна на всей территории ХФУ. Ведет себя точно так же, как this-scope в любом другом CFC, за исключением того, что некоторые переменные this-scoped имеют особое значение (например,
this.name
,this.datasource
, так далее). Эти переменные специального значения могут быть изменены для каждого сеанса или для каждого запроса в соответствующих обработчиках, но, похоже, они применяются ко всей системе (то есть: не для конкретного сеанса или запроса, вносящего изменения в настройки). В нормальных ХФУthis
область видимости используется для предоставления общедоступных переменных, но поскольку нет общедоступного экземпляра Application.cfc, нет смысла использоватьthis
выход за рамки этих специальных настроек. Если кто-то хочет, чтобы переменные были доступны для всех методов в CFC, используйте область видимости переменных, как обычно. Вопреки чьему-то совету здесь переменные этой области не совпадают с переменными области приложения. - Область запроса также доступна по всему CFC (псевдо-конструктор и методы). Они также будут доступны для вызывающего кода шаблонов, вызываемых позже в запросе, как и для любых других переменных области запроса.
- Область применения: недоступна в псевдо-конструкторе, даже после
this.name
настройка сделана. Становится доступным только в onApplicationStart() и далее оттуда.- Область действия сеанса: аналогично, недоступна в псевдо-конструкторе или onApplicationStart()l и только до onSessionStart().
Я продемонстрировал это в сообщении в блоге (предоставлен тестовый код) здесь. это слишком долго, чтобы включать здесь, но материал выше суммирует это.
Пожалуйста, смотрите комментарии, как это выглядит ниже работы поста, но это не так. Если вы сбросите эту область, появится новое значение, но оно не изменит никаких настроек приложения.
Вы можете изменить любые настройки приложения в любом месте; однако, поскольку псевдо-конструктор запускается каждый раз, когда запрашивается страница, вам нужно будет постоянно менять настройки после запуска псевдо-конструктора. Область применения приложения недоступна в псевдо-конструкторе, поэтому вы можете сделать это в функциях onRequestStart или onRequest. Я сделал простой тест переназначения пользовательских тегов в соответствии с условием в функции 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/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, но я не пробовал это в псевдо-конструкторе.