Java 如何确定ColdFusion对象所在的上下文?

Java 如何确定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中做些什么来告诉我有关调用它的上下文的一些事情(任何事情!)?因为所有东西最终都(至少)存在于某种范围内,并且

因此,考虑到我有一个该组件的实例:

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>