Java 被叫人认识打电话的人吗?

Java 被叫人认识打电话的人吗?,java,reflection,Java,Reflection,我有一个Java实用程序包,它可以被多个服务(用Java编写)用来执行一些实用程序任务 假设Java实用程序包名为U,其中一个服务名为S 我的问题是,包U的函数F是否能够确定S调用了哪个服务? 可以有多个服务S1、S2、,Sn调用F。我需要知道在调用时,哪个服务Sx正在调用该特定F。您可以使用类似于以下的方法,只需要创建一个函数findServiceContainingClass将类名映射到服务(或null): void被调用方(){ StackTraceElement[]st=新的Runtim

我有一个Java实用程序包,它可以被多个服务(用Java编写)用来执行一些实用程序任务

假设Java实用程序包名为U,其中一个服务名为S

我的问题是,包U的函数F是否能够确定S调用了哪个服务?
可以有多个服务S1、S2、,Sn调用F。我需要知道在调用时,哪个服务Sx正在调用该特定F。

您可以使用类似于以下的方法,只需要创建一个函数
findServiceContainingClass
将类名映射到服务(或null):

void被调用方(){
StackTraceElement[]st=新的RuntimeException().getStackTrace();
对于(int i=1;i

但是,根据调用方的不同,使代码行为不同被认为是不好的做法。我只会在万不得已的情况下使用这些代码。(在调试过程中,可以在断点条件下使用它。可能这就是您想要的。)

您可以使用类似于以下的方法,只需要创建一个函数
findServiceContainingClass
将类名映射到服务(或null):

void被调用方(){
StackTraceElement[]st=新的RuntimeException().getStackTrace();
对于(int i=1;i

但是,根据调用方的不同,使代码行为不同被认为是不好的做法。我只会在万不得已的情况下使用这些代码。(在调试过程中,在断点条件下使用它是可以的。也许这就是您想要的。)

如果需要由该实用程序方法执行某些特定于服务的代码,我将在实用程序类中声明一个接口,并让服务将其实例传递给该方法

下面是一个人为的例子:

public class Utility {

    public interface UtilityInterface {

        public void specificBehavior( Object arg );
    }

    public void utilityMethodF( UtilityInterface utilityInterface, Object... args ) {

        // perform work with args or whatever

        utilityInterface.specificBehavior( null );

        // perform work with args or whatever
    }

}

如果该实用程序方法需要执行某些特定于服务的代码,我将在实用程序类中声明一个接口,并让服务将其实例传递给该方法

下面是一个人为的例子:

public class Utility {

    public interface UtilityInterface {

        public void specificBehavior( Object arg );
    }

    public void utilityMethodF( UtilityInterface utilityInterface, Object... args ) {

        // perform work with args or whatever

        utilityInterface.specificBehavior( null );

        // perform work with args or whatever
    }

}

Java中的面向对象编程声明您的服务是调用的范围,而不是其他(忘记
静态
)。所以,除了将
s
instance作为参数传递之外,找不到调用实例方法的人

但这并不意味着这是不可能的

如果只需要知道调用方的类型,可以使用
Thread.currentThread().getStackTrace()

正如我在开始时所说的,它完全是反目标Java代码

如果您需要引用确切的实例,您可能应该添加调用者作为调用参数。我假设,若您想引用调用者,则被调用者的代码是由您编写的,所以您可以这样做对我来说,这将是最好的选择,因为如果您需要被调用方范围内的调用方,您应该直接传递它。另一个选项是在
U
中的ThreadLocal上设置调用方,但您不相信开发人员每次都会这样做

如果无法更改接口,并且U是接口,则可以创建
U
builder对象:

public class UBuilder {
  public U getS(final S caller) {
    Proxy.newProxyInstance(getClass().getClassLoader(), U.class, 
                           new InvocationHandler() {
      public Object invoke(Object proxy, Method method, 
                           Object[] args) throws Throwable {
        // store caller value on some ThreadLocal variable
        try {
          method.invoke(proxy, args);
        } finally {
          // remove caller from ThreadLocal variable
        }
      }
    }
  }
}
在这之后,您就有了引用
S
实例的附加调用上下文(
ThreadLocal

如果
U
不是interface
Javassist
CgLib
或类似的方法会有所帮助,但前提是调用的方法不是静态的或最终的

如果
F
是静态的或最终的
我只能看到非常粗俗的答案。也许可以通过某种方式创建自己的接口,模仿
U
,并在
InvocationHandler
中转发方法调用。当然,S应该引用此接口,而不是直接引用
U


希望有帮助。

Java中的面向对象编程声明您的服务是调用的范围,而不是其他(忘记
静态
)。所以,除了将
s
instance作为参数传递之外,找不到调用实例方法的人

但这并不意味着这是不可能的

如果只需要知道调用方的类型,可以使用
Thread.currentThread().getStackTrace()

正如我在开始时所说的,它完全是反目标Java代码

如果您需要引用确切的实例,您可能应该添加调用者作为调用参数。我假设,若您想引用调用者,则被调用者的代码是由您编写的,所以您可以这样做对我来说,这将是最好的选择,因为如果您需要被调用方范围内的调用方,您应该直接传递它。另一个选项是在
U
中的ThreadLocal上设置调用方,但您不相信开发人员每次都会这样做

如果无法更改接口,并且U是接口,则可以创建
U
builder对象:

public class UBuilder {
  public U getS(final S caller) {
    Proxy.newProxyInstance(getClass().getClassLoader(), U.class, 
                           new InvocationHandler() {
      public Object invoke(Object proxy, Method method, 
                           Object[] args) throws Throwable {
        // store caller value on some ThreadLocal variable
        try {
          method.invoke(proxy, args);
        } finally {
          // remove caller from ThreadLocal variable
        }
      }
    }
  }
}
在这之后,您就有了引用
S
实例的附加调用上下文(
ThreadLocal

如果
U
不是interface
Javassist
CgLib
或类似的方法会有所帮助,但前提是调用的方法不是静态的或最终的

如果
F
是静态的或最终的
我只能看到非常粗俗的答案。也许可以通过某种方式创建自己的接口,模仿
U
,并在
InvocationHandler
中转发方法调用。当然,S应该引用此接口,而不是直接引用
U

希望有帮助。

没有什么好办法。