我有一個Java實用程序包,可以由多個服務(用Java編寫)用於執行一些實用程序任務。被叫方是否知道來電者?
比方說在Java應用程序包的名稱是U和服務的一個是S.現在全叫U的函數F
我的問題是,是否有一種方法,其中封裝的函數F U是能夠確定S所稱的服務? 可以有多個服務S1,S2,...,Sn調用F.我需要知道一個調用,哪個Service Sx正在調用那個特定的F.
我有一個Java實用程序包,可以由多個服務(用Java編寫)用於執行一些實用程序任務。被叫方是否知道來電者?
比方說在Java應用程序包的名稱是U和服務的一個是S.現在全叫U的函數F
我的問題是,是否有一種方法,其中封裝的函數F U是能夠確定S所稱的服務? 可以有多個服務S1,S2,...,Sn調用F.我需要知道一個調用,哪個Service Sx正在調用那個特定的F.
您可以使用類似下面的內容,只需要然而,它被認爲是不好的做法,使代碼的行爲不同,這取決於主叫
void callee() {
StackTraceElement[] st = new RuntimeException().getStackTrace();
for (int i = 1; i < st.length; i++) {
Service service = findServiceContainingClass(st[i].getClassName());
if (service != null) break;
}
// ... use service
}
:創建一個函數映射findServiceContainingClass
類名服務(或空)。我只會將這些代碼作爲最後的手段。 (可以在調試過程中在斷點狀態下使用它,也許這就是你想要的)
如果需要一些由該實用程序方法執行的服務特定的代碼,我會聲明一個接口在實用程序類中,並將這些服務的實例傳遞給該方法。
這是一個人爲的例子:在Java中
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
}
}
面向對象的編程指出您的服務範圍進行調用,沒有別的(忘了static
)。因此,除了傳遞S
實例作爲參數之外,沒有正常的方法可以找到誰在調用實例的方法。
但這並不意味着它是不可能的。
如果你只需要知道什麼是來電者的類型,你可以使用Thread.currentThread().getStackTrace()
:
StackTraceElement[] elements = Thread.currentThread().getStackTrace()
StackTraceElement caller = elements[elements.length - 2];
printLn(caller.getClassName());
正如我在開始的時候是完全反客觀Java代碼表示。
如果您需要參考確切實例,您可能應該添加調用者作爲調用參數。我假設,如果你想引用調用者,被調用者的代碼是由你寫的,所以你能夠做到。 至於我這將是最好的選擇,因爲如果你需要調用者在被調用者的範圍內,你應該直接傳遞它。其他選項是在0123B的ThreadLocal上設置調用者,但是您沒有信心開發人員每次都會這樣做。
如果接口不能改變,U是接口,您可以創建U
生成器對象:
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
沒有接口,Javassist
,CgLib
或類似,將有助於東西,但是隻有當調用的方法是不是靜態或決賽。
如果F
是靜態的或最終的我只看到極其駭人的答案。也許創建自己的界面模仿U
,轉發方法調用InvocationHandler
可能是某種方式。當然S應該直接指這個接口,而不是U
。
希望它有幫助。
沒有什麼好的方法。這聽起來像你應該將具體信息傳遞給'F'關於誰叫它。 –
爲什麼實用程序類需要知道哪個客戶端類正在調用它?實用程序類將如何改變其行爲以適應不同的客戶端類型? – Bobulous
看看您是否可以使用F的任何方法參數並對其進行處理。請在服務中調用方法的任何方法參數(如果可能)中設置服務名稱或代碼值。 – Nishant