Java 如何确定ColdFusion对象所在的上下文?
因此,考虑到我有一个该组件的实例: foo.cfcJava 如何确定ColdFusion对象所在的上下文?,java,coldfusion,cfc,cfml,Java,Coldfusion,Cfc,Cfml,因此,考虑到我有一个该组件的实例: foo.cfc <cfcomponent> <cffunction name="locateMe"> <cfreturn "I don't know where I live!"> </cffunction> </cfcomponent> 我想知道的是,我可以在foo.cfc中做些什么来告诉我有关调用它的上下文的一些事情(任何事情!)?因为所有东西最终都(至少)存在于某种范围内,并且
<cfcomponent>
<cffunction name="locateMe">
<cfreturn "I don't know where I live!">
</cffunction>
</cfcomponent>
我想知道的是,我可以在foo.cfc中做些什么来告诉我有关调用它的上下文的一些事情(任何事情!)?因为所有东西最终都(至少)存在于某种范围内,并且所有范围都是一种对象,所以我想说的是,我真的想从给定的实例化对象中确定包含的对象。最后,根据我上面的示例片段,以某种方式构建foo.cfc,以便类似这样的内容可以作为我的输出:
I live within a "class coldfusion.runtime.Struct" instance!
I live within a "class coldfusion.runtime.VariableScope" instance!
I live within a "component cfjunk.fooParent" instance!
其中,这些值中的每一个都可以通过检查传递getMetaData
实际包含对象引用的结果来确定
更新正如Micah在评论中所建议的,我已经添加了“Java”标记,因为我怀疑他可能是正确的,因为解决方案可能在于使用Java进行内省
更新
与其说这是一个纯粹的学术讨论,不如让我解释一下为什么我需要这个
我正在使用cform和includes返回对我的数据的引用,如下所示:
var user = model("User").findOne(where="id=123", include="AuthSource", returnAs="object");
这将向我返回一个对象,我可以这样引用:
user.id // property of the "User" model
user.reset() // method on the "User" model
user.AuthSource.id // property of the "AuthSource" model
user.AuthSource.authenticate(password) // method on the "AuthSource" model
现在,在我的“AuthSource.authenticate”方法中,我想了解包含在其中的“User”对象。否则,我将不得不像这样调用函数:
user.AuthSource.authenticate(user, password) // note the redundancy in the use of "user"
我应该能够依靠这样一个事实,即我正在通过用户对象调用AuthSource模型上的方法,并从该方法中实际读取该对象。我已经很久没有做coldfusion了,所以请原谅我的伪代码,但我想在这种情况下通常会做什么,就是让父对象在实例化子对象时将其自身的副本发送给子对象。这在许多OOP设计模式中使用,其中两个对象需要以两种方式相互通信,而不仅仅是子对象上的父调用方法 因此,您的子类的定义如下:
<cfcomponent>
<cffunction name="init">
<cfargument name="parentParam" required="yes" type="object">
<cfset this.parent = parentParam >
<cfreturn this>
</cffuncton>
<cffunction name="locateMe">
<cfreturn "I belong to #this.parent.className# !">
</cffunction>
<cffunction name="doOtherStuff">
<cfreturn "I do stuff with my parent: #this.parent.className# !">
</cffunction>
</cfcomponent>
然后当你使用它的时候
<cfset myParent.child = createObject("component", "Object").init(myParent) />
#myparent.locateMe()#
#myparent.doOtherStuff()#
#myparent.locateMe()#
#myparent.doOtherStuff()#
parentParam将是名为“init”的构造函数方法中的必需参数,因此子级始终具有对其父级的引用。然后,您的所有方法都可以使用this.parent来处理它。在我的代码示例中,我这样做了#this.parent.className#,但不知道coldfusion对象是否具有这样的属性。也许您可以使用反射或某种元编程来做同样的事情
请注意:据我所知,coldfusion不支持内置的构造函数,因此我向您展示的是来自此站点的社区标准最佳实践:
我很抱歉你在做colfusion顺便说一句…;) 我删除了以前的所有内容,因为它似乎没有什么帮助。根据你后来的评论,我认为以下建议可能更符合你的目标
// Object
<cfcomponent displayname="Object">
<cffunction name="init">
<cfargument name="username" type="string">
<cfscript>
variables.username = arguments.username;
variables.authSource = CreateObject('component','AuthSource').init();
</cfscript>
<cfreturn this>
</cffunction>
<cffunction name="authenticate">
<cfargument name="password" type="string">
<cfreturn variables.authSource.authenticate(variables.username,arguments.password)>
</cffunction>
</cfcomponent>
<cfcomponent displayname="AuthSource">
<cffunction name="init">
<cfreturn this>
</cffunction>
<cffunction name="authenticate">
<cfargument name="username" type="string">
<cfargument name="password" type="string">
.... DO STUFF ...
<cfreturn ...>
</cffunction>
</cfcomponent>
<cfscript>
objUser = CreateObject('component','Object').init('SomeUserName');
// Authenticate
objUser.authenticate('SomePassword');
</cfscript>
//对象
variables.username=arguments.username;
variables.authSource=CreateObject('component','authSource').init();
.... 做些事情。。。
objUser=CreateObject('component','Object').init('SomeUserName');
//鉴定
objUser.authenticate('SomePassword');
这样,AuthSource就不需要知道父对象的情况,但同时进行身份验证的人不需要再次传入用户名。对象(父对象)有一个用于身份验证的包装器方法,该方法添加到用户名中
这是任何进一步的帮助吗?我知道这现在不相关,但是下一版本的CF(宙斯)有一个功能来做这件事 是的,手动跟踪对包含对象的引用是我的第一个想法。不过,我希望有一个解决办法。我会等一等,看看是否有其他人会提出不同的方法。谢谢,CF真的没那么糟糕!这种方法的一个不幸结果是,对象的CFDump变成了无限循环(啊,这是有道理的,因为每个对象都有一个对另一个对象的引用。因此,如果你想避免引用子对象中的父对象,我想你必须使用coldfusion版本的反射,看看是否有办法找到对子对象的所有引用。我甚至不知道如何用我更熟悉的语言来做。我知道Coldfusion并没有那么糟糕,我是从它开始的。Beats PHP!:)我不得不说,这里的解决方案可能就是我看待它的方式。我认为主要的问题是,在组件内部,您不应该真正访问组件外部的数据,这就排除了直接访问变量的可能性。就我所能回忆起的,唯一的方法是传入父范围,如这里所详述的。出于兴趣,你为什么要这么做?好问题。我想知道JAVA是否有一些类似内省的函数来决定这类事情。也许你可以通过添加一个java标记来扩展你的问题。为什么在这个问题上随机投反对票?真奇怪……我很欣赏你的回答,但基本上你的回答是“试着按你的要求去做不是个好主意”。你可能是对的,但这并不是问题的答案。和我如何改变我的真实例子一样——我知道我可以改变它使它工作,但这并不是真正的问题所在。也许这毕竟还是一个学术性的问题。我可以看到你所追求的东西的用处——我可以在我目前正在进行的项目中利用同样的东西。我解决这个问题的方法是将父对象传递给子对象,但是正如前面提到的
<cfcomponent>
<cffunction name="init">
<cfargument name="parentParam" required="yes" type="object">
<cfset this.parent = parentParam >
<cfreturn this>
</cffuncton>
<cffunction name="locateMe">
<cfreturn "I belong to #this.parent.className# !">
</cffunction>
<cffunction name="doOtherStuff">
<cfreturn "I do stuff with my parent: #this.parent.className# !">
</cffunction>
</cfcomponent>
<cfset myParent.child = createObject("component", "Object").init(myParent) />
#myparent.locateMe()#
#myparent.doOtherStuff()#
// Object
<cfcomponent displayname="Object">
<cffunction name="init">
<cfargument name="username" type="string">
<cfscript>
variables.username = arguments.username;
variables.authSource = CreateObject('component','AuthSource').init();
</cfscript>
<cfreturn this>
</cffunction>
<cffunction name="authenticate">
<cfargument name="password" type="string">
<cfreturn variables.authSource.authenticate(variables.username,arguments.password)>
</cffunction>
</cfcomponent>
<cfcomponent displayname="AuthSource">
<cffunction name="init">
<cfreturn this>
</cffunction>
<cffunction name="authenticate">
<cfargument name="username" type="string">
<cfargument name="password" type="string">
.... DO STUFF ...
<cfreturn ...>
</cffunction>
</cfcomponent>
<cfscript>
objUser = CreateObject('component','Object').init('SomeUserName');
// Authenticate
objUser.authenticate('SomePassword');
</cfscript>