MethodLogger Aspect
Here is my MethodLogger aspect that I will create:
1
<cfcomponent output="false" implements="wirebox.system.aop.MethodInterceptor" hint="A simple interceptor that logs method calls and their results">
2
3
<--- Dependencies --->
4
<cfproperty name="log" inject="logbox:logger:{this}">
5
6
<--- init --->
7
<cffunction name="init" output="false" access="public" returntype="any" hint="Constructor">
8
<cfargument name="logResults" type="boolean" required="false" default="true" hint="Do we log results or not?"/>
9
<cfscript>
10
instance = {
11
logResults = arguments.logResults
12
};
13
14
return this;
15
</cfscript>
16
</cffunction>
17
18
<--- invokeMethod --->
19
<cffunction name="invokeMethod" output="false" access="public" returntype="any" hint="Invoke an AOP method invocation">
20
<cfargument name="invocation" required="true" hint="The method invocation object: wirebox.system.aop.MethodInvocation">
21
<cfscript>
22
var refLocal = {};
23
var debugString = "target: #arguments.invocation.getTargetName()#,method: #arguments.invocation.getMethod()#,arguments:#serializeJSON(arguments.invocation.getArgs())#";
24
25
// log incoming call
26
log.debug(debugString);
27
28
// proceed execution
29
refLocal.results = arguments.invocation.proceed();
30
31
// result logging and returns
32
if( structKeyExists(refLocal,"results") ){
33
if( instance.logResults ){
34
log.debug("#debugString#, results:", refLocal.results);
35
}
36
return refLocal.results;
37
}
38
</cfscript>
39
</cffunction>
40
41
</cfcomponent>
Copied!
You can see that I do some DI via annotations:
1
<--- Dependencies --->
2
<cfproperty name="log" inject="logbox:logger:{this}">
Copied!
A normal constructor with one optional argument for logging results:
1
<--- init --->
2
<cffunction name="init" output="false" access="public" returntype="any" hint="Constructor">
3
<cfargument name="logResults" type="boolean" required="false" default="true" hint="Do we log results or not?"/>
4
<cfscript>
5
instance = {
6
logResults = arguments.logResults
7
};
8
9
return this;
10
</cfscript>
11
</cffunction>
Copied!
And our invokeMethod implementation:
1
<--- invokeMethod --->
2
<cffunction name="invokeMethod" output="false" access="public" returntype="any" hint="Invoke an AOP method invocation">
3
<cfargument name="invocation" required="true" hint="The method invocation object: wirebox.system.aop.MethodInvocation">
4
<cfscript>
5
var refLocal = {};
6
var debugString = "target: #arguments.invocation.getTargetName()#,method: #arguments.invocation.getMethod()#,arguments:#serializeJSON(arguments.invocation.getArgs())#";
7
8
// log incoming call
9
log.debug(debugString);
10
11
// proceed execution
12
refLocal.results = arguments.invocation.proceed();
13
14
// result logging and returns
15
if( structKeyExists(refLocal,"results") ){
16
if( instance.logResults ){
17
log.debug("#debugString#, results:", refLocal.results);
18
}
19
return refLocal.results;
20
}
21
</cfscript>
22
</cffunction>
Copied!
As you can see, the before advice part is what happens before the execution of the real method (or more aspects) occurrs. So everything before the call to arguments.invocation.proceed():
1
var refLocal = {};
2
var debugString = "target: #arguments.invocation.getTargetName()#,method: #arguments.invocation.getMethod()#,arguments:#serializeJSON(arguments.invocation.getArgs())#";
3
4
// log incoming call
5
log.debug(debugString);
Copied!
Then we execute the real method or more aspects (we do not do anything around the method call):
1
// proceed execution
2
refLocal.results = arguments.invocation.proceed();
Copied!
Finally, we do the after advice part which happens after the method or other aspects fire and results are returned:
1
// result logging and returns
2
if( structKeyExists(refLocal,"results") ){
3
if( instance.logResults ){
4
log.debug("#debugString#, results:", refLocal.results);
5
}
6
return refLocal.results;
7
}
Copied!
That's it. I have succesfully created an aspect. What's next!
Copy link
Edit on GitHub