One question I have seen out on Forums a bit is why application scoped variables do not initialize after being set. The answer lies in the purpose behind the scope itself. What do I mean?, and what is a scope?. CF uses scopes to define where the variable should persist. Variables with no scope are always assumed to be part of the variables scope.
<cfset variables.test = “string”> is the same as <cfset test = “string”>
Variables scoped variables persists only on the page that it is set on; With some exceptions to the rule. Sessions scoped variables can be called/ referenced for the life of the users session. Application scoped variables persist for the life of the application. This means that you can reference #application.datasource# on any page and it will ONLY be initialized when the application is restarted. This can be handy if the value of this variable will remain static for the life of the application meaning till CF services are restarted. Now obviously there are other scopes out there which I can cover in another post, but for now we are focused on the application scope.
Why is it important to use application scoped variables if it only refreshes when the application is started?. Well, look at it this way, you can use <cfset datasource = “test”>, however you will need to define this on every page you call. Not only is it bad practice to do so, but every time it is initialized, you are using up space in memory to reserve for that call. So if you are building an application to scale at a later date, then you want to make sure your code is utilizing your JVM memory as efficiently as possible. It is very easy to run into memory leaks. One way I have seen this happen is a developer using the request scope to initialize all there variables. This may not seem so bad, but when you multiply that by the thousands of requests you could get, it can be easy to overwhelm your JVM.
So back to the subject. If you know that certain variables will not need to be re initialized on every request or every session, then place it in your application scope. This is great for variables like datasource or other variables you intend to use globally. The only draw back is that during development if you are changing this value you need to remember to restart your CF instance in order for your application to see the new value. Here is an example of a Application.cfc with application scoped variables.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!— | |
— Application | |
— ———– | |
— | |
— author: Matthew | |
— date: 5/4/14 | |
—> | |
<cfcomponent displayname="Application" output="true" hint="Handle the application."> | |
<cfset THIS.Name = "AppCFC" /> | |
<cfset THIS.ApplicationTimeout = CreateTimeSpan( 0, 0, 1, 0 ) /> | |
<cfset THIS.SessionManagement = true /> | |
<cfset THIS.SetClientCookies = false /> | |
<cffunction name="OnApplicationStart" access="public" returntype="boolean" output="false" hint=""> | |
<cfset application.url ="http://url.domain.com"> | |
<cfset application.datasource ="datasource"> | |
<cfset application.smtp ="emailserver.domain.com"> | |
<cfreturn true /> | |
</cffunction> | |
<cffunction name="OnSessionStart" access="public" returntype="void" output="false" hint=""> | |
<cfset session.variable = "string"> | |
<cfreturn /> | |
</cffunction> | |
<cffunction name="OnRequestStart" access="public" returntype="boolean" output="false" hint=""> | |
<cfargument name="TargetPage" type="string" required="true"/> | |
<cfreturn true /> | |
</cffunction> | |
<cffunction name="OnRequest" access="public" returntype="void" output="true" hint=""> | |
<cfargument name="TargetPage" type="string" required="true"/> | |
<cfinclude template="#ARGUMENTS.TargetPage#" /> | |
<cfreturn /> | |
</cffunction> | |
<cffunction name="OnRequestEnd" access="public" returntype="void" output="true" hint=""> | |
<cfreturn /> | |
</cffunction> | |
<cffunction name="OnSessionEnd" access="public" returntype="void" output="false" hint=""> | |
<cfargument name="SessionScope" type="struct" required="true"/> | |
<cfargument name="ApplicationScope" type="struct" required="false" default="#StructNew()#"/> | |
<cfreturn /> | |
</cffunction> | |
<cffunction name="OnApplicationEnd" access="public" returntype="void" output="false" hint=""> | |
<cfargument name="ApplicationScope" type="struct" required="false" default="#StructNew()#"/> | |
<cfreturn /> | |
</cffunction> | |
<cffunction name="OnError" access="public" returntype="void" output="true" hint=""> | |
<cfargument name="Exception" type="any" required="true"/> | |
<cfargument name="EventName" type="string" required="false" default=""/> | |
<cfmail to="toemail@mjddesignconcepts.com" from="fromemail@mjddesignconcepts.com" subject="[ERROR]" type="html"> | |
<cfdump var="#EventName#"> | |
<cfdump var="#Exception#"> | |
</cfmail> | |
<cfreturn /> | |
</cffunction> | |
</cfcomponent> |