Java 被叫人认识打电话的人吗?
我有一个Java实用程序包,它可以被多个服务(用Java编写)用来执行一些实用程序任务 假设Java实用程序包名为U,其中一个服务名为S 我的问题是,包U的函数F是否能够确定S调用了哪个服务?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
可以有多个服务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
希望有帮助。没有什么好办法。