To implement a before advice, you must define the following method in
your component:
before(method, args, target)
Argument Type Description
method coldspring.aop.Method The Method object wraps the original
method call. Proceed() will automatically be called for you on the
Method object after your BeforeAdvice executes (to execute the
original method call )
args Struct The argument collection that will be passed to the
method call in the Method object
target Component The target object of the method call in the
Method object (useful if your advice is very generic and needs to
inspect the component that it is being applied to)
You don't have a method argument in your advice, so there's nothing on
which to call proceed().
--
mxAjax / CFAjax docs and other useful articles:
http://www.bifrost.com.au/blog/
The generated proxy - like all good CFCs - has output="false" so your
test.cfc output is suppressed.
If you make the method return something, you'll see it gets correctly
returned (and the code is working)
It's generally considered not good practice to have CFCs outputting HTML.
--
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/
"If you're not annoying somebody, you're not really alive."
-- Margaret Atwood
Yes he does. Here's is his advice:
testBeforeAdvice.cfc:
------------------------------------------
<cfcomponent displayname="testBeforeAdvice"
extends="coldspring.aop.BeforeAdvice" output="false">
<cffunction name="before" access="public" returntype="any"
output="true">
<cfoutput>BeforeAdvice<br></cfoutput>
<cfreturn>
</cffunction>
</cfcomponent>
There's a before() method defined.
--
Regardless, Sean is right about the output attribute of course.
On Tue, Mar 18, 2008 at 12:38 PM, Chris Scott <chris.s...@gmail.com> wrote:
> The arguments to both before and afterReturning advice types are both
> optional. The theory there is, you only need to define what you are
> interested in working with. I always use the full method signature myself,
> but you certainly don't need to. With around advice, you DO need to define
> MethodInvocation as a parameter, because you are responsible for calling
> proceed on the chain of interceptors.
>
> Chris
>
>
> On Mon, Mar 17, 2008 at 9:10 PM, James Holmes <james....@gmail.com>
> wrote:
> >
> >
> > Yes, the before() method is there, but doesn't it need a "method"
> > argument of the type coldspring.aop.Method so that there's something
> > on which to call Proceed()? Or does that get passed in and used
> > automatically anyway (even if it's not defined, since arbitrary
> > arguments can be passed to a CF method anyway)?
--
On Tue, Mar 18, 2008 at 5:03 PM, jax <rea...@gmail.com> wrote:
> Have a look at the beforeAdvice component en de test component. Both
> have an output=false attribute set on the component level,
> and both have an output=true set on the method executed ( 'before' and
> 'test'). But only the before method produced output...
--
ColdSpring creates an internal proxy bean on the fly that pretends to
be your component. When you call getBean(), you get this instead of
your real component. In your case, it looks like this:
<cfcomponent name="coldspring.aop.framework.tmp.bean_C102FFAD188B1169E6325F2105ADF039"
displayname="AopProxyBean"
extends="ColdSpringTest.model.test"
hint="Abstract Base Class for Aop Proxy Beans"
output="false">
<cffunction name="init" access="public"
returntype="ColdSpringTest.model.test" output="false">
<cfargument name="target" type="any" required="true" />
<cfset variables.target = arguments.target />
<cfreturn this />
</cffunction>
<cffunction name="setAdviceChains" access="public" returntype="void"
output="false">
<cfargument name="adviceChains" type="struct" required="true" />
<cfset variables.adviceChains = arguments.adviceChains />
</cffunction>
<cffunction name="getAdviceChains" access="public"
returntype="struct" output="false">
<cfreturn variables.adviceChains />
</cffunction>
<cffunction name="callMethod" access="public" returntype="any">
<cfargument name="methodName" type="string" required="true" />
<cfargument name="args" type="struct" required="true" />
<cfset var adviceChain = 0 />
<cfset var methodInvocation = 0 />
<cfset var rtn = 0 />
<cfset var method = 0 />
<!--- if an advice chain was created for this method, retrieve a
methodInvocation chain from it and proceed --->
<cfif StructKeyExists(variables.adviceChains, arguments.methodName)>
<cfset method =
CreateObject('component','coldspring.aop.Method').init(variables.target,
arguments.methodName, arguments.args) />
<cfset adviceChain = variables.adviceChains[arguments.methodName] />
<cfset methodInvocation = adviceChain.getMethodInvocation(method,
arguments.args, variables.target) />
<cfreturn methodInvocation.proceed() />
<cfelse>
<!--- if there's no advice chains to execute, just call the method --->
<cfinvoke component="#variables.target#"
method="#arguments.methodName#"
argumentcollection="#arguments.args#"
returnvariable="rtn">
</cfinvoke>
<cfif isDefined('rtn')>
<cfreturn rtn />
</cfif>
</cfif>
</cffunction>
</cfcomponent>
On Tue, Mar 18, 2008 at 5:19 PM, jax <rea...@gmail.com> wrote:
>
> Can you elaborate on this ? What is the proxy in this case? the
> BeforeAdvice?
> How does that explain the behaviour?
>
> please forgive my ignorance.. I'm (obviously) a newby in the
> ColdSpring world :-)
>
>
> On Mar 18, 9:13 am, "James Holmes" <james.hol...@gmail.com> wrote:
> > Yes, but it's the proxy that's actually being called.
--
<cffunction name="proceed" access="public" returntype="any" output="false"
hint="Executes captured method on target object">
<cfset var rtn = 0 />
<cfif isRunnable()>
<cfinvoke component="#variables.target#"
method="#variables.method#"
argumentcollection="#variables.args#"
returnvariable="rtn">
</cfinvoke>
<cfset variables.runnable = false />
<cfif isDefined('rtn')>
<cfreturn rtn />
</cfif>
</cfif>
</cffunction>
This proceed() method is how the proxy runs your method after the
beforeAdvice is run. Notice that it has output="false" - this prevents
the output from showing.
To prove this, take ColdSpring out of the equation completely and make
up a simple test based on the code in proceed():
test1.cfc:
<cfcomponent output="no">
<cffunction name="proceed" access="public" returntype="any"
output="false" hint="Executes captured method on target object">
<cfset var rtn = 0 />
<cfinvoke component="test2"
method="doit"
returnvariable="rtn">
</cfinvoke>
<cfif isDefined('rtn')>
<cfreturn rtn />
</cfif>
</cffunction>
</cfcomponent>
test2.cfc:
<cfcomponent output="no">
<cffunction name="doit" access="public" returntype="string" output="yes">
<cfoutput>HELLO OUTPUT</cfoutput>
<cfset myResult="foo">
<cfreturn myResult>
</cffunction>
</cfcomponent>
test.cfm:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>
<body>
<cfset myobj = createobject("component","test1")>
<cfset ret = myobj.proceed()>
<cfset myobj2 = createobject("component","test2")>
<cfset ret2 = myobj2.doit()>
</body>
</html>
So the first bit, myobj, calls the doit() method via proceed(). The
second one calls it directly. You will see only one output of "HELLO
OUTPUT."
I've got the following snippit saved in CFEclipse:
<cfsavecontent variable="t">
<cfdump var="#$${Variable}#">
</cfsavecontent>
<cffile action="write" file="/tmp/a.html" output="#t#">
--
Tom
The cfdump to console is interesting, giving you things like
==> /opt/coldfusion8/logs/cfserver.log <==
struct
SEARCHVALUE: tron
USERNAME: erg
Handy for simple things I suppose, but if you are looking at something
fairly complicated, having the full HTML dump on a file can be
handier.
--
Tom
I would never expect screen output from a proxied component.
It sounds like your use case is for the (rare, hopefully !) case when
something isn't working, in which case that's what debuggers are for.
I don't find it a bind to go in and add dumps to a file (or cflog
statements) where I need to either.
I've never had a need to debug the internals of ColdSpring either.
--
Tom
On Wed, Mar 19, 2008 at 11:58 PM, jax <rea...@gmail.com> wrote:
>
> Tom: It's like this: I don't need a car to get to work, I can get
> there by train as well.
> I just like the car better, and fortunately no one tells me I should
> take the train simply because he/she feels that is how one is supposed
> to commute ;-)
--
Where do all those electrons come from ?
--
Tom
Ahh, Mr Fusion :-)
http://zedomax.com/blog/wp-content/uploads/2007/09/mr_fusion.jpg
--
Tom
What? Nuclear Fusion? Haven't you upgraded to Cold Fusion yet? I hear
Cold Fusion is the new Nuclear Fusion.
(and now, we return to our regularly scheduled relevant emails....)
--
Matt Williams
"It's the question that drives us."