2014-12-04 122 views
0

我遇到了一個很明顯的問題,雖然我不知道如何解決它。 我有2個類,其中1個是Interceptor。攔截類中的靜態變量java

@Stateless 
@Interceptors(AutoId.class) 
public class TestClass { 
    private static final Logger LOG = Logger.getLogger(RepositoryBean.class.getName()); 

    public void executeUpdate(){ 
     int k=0; 
     for (int i = 0; i < 1000000; i++) { 
      for (int j = 0; j < 100000; j++) { 
       for (int r = 0; r < 1000000; r++) { 
        k = 1; 
       } 
      } 
     } 
     getLogger().log(Level.INFO, "Current time some time ago was "+AutoId.MyTime/1000); 
     } 
    private Logger getLogger() { 
     return Logger.getLogger(getClass().getCanonicalName()); 
    }} 

,這裏是攔截器類:

public class AutoId {   
    public static Long MyTime; 

    @AroundInvoke 
    public Object addLog(InvocationContext context) throws Exception { 
     MyTime= System.currentTimeMillis();  
     return context.proceed();  
    } 
} 

一個明顯的問題是,如果我在幾秒鐘運行該應用程序(當它部署在GlassFish服務器上),然後我跑另一個副本它會用新的時間重寫MyTime變量,因此,這兩個程序將同時打印。 其中一個明顯的解決方案是在executeUpdate內部創建一個可以節省MyTime值的變量,但這對於我正在處理的真實項目並不好。

我被告知我可能想用ContextResolver和@Context做些什麼。 儘管如何解決這個問題? 謝謝。

編輯 我只加入找到了一個解決方案,但我不認爲這是最好的

public class AutoId {   
    private static Long[] MyTime = new Long[1000]; 

    @AroundInvoke 
    public Object addLog(InvocationContext context) throws Exception { 
     MyTime[(int)Thread.currentThread().getId()]= System.currentTimeMillis();  
     return context.proceed();  
    } 

    public static Long MyTime(){ 
    return MyTime[(int)Thread.currentThread().getId()]; 
    } 
} 

命名陣列的方式方法同樣可以儘量減少主類代碼更改() After AutoId.MyTime - > AutoId.MyTime()

這仍然不是最好的主意,儘管它不會導致重寫變量了。

EDIT2請不要介意executeUpdate()過程中的所有代碼。它只是以一些需要完成工作的方式編寫的,以便我可以再執行一個副本並打印出AutoId.MyTime。這個變量的值是唯一重要的。

另外,如果我沒有使用Interceptor,並且在類中創建AutoId變量以在任何其他過程(這是攔截器)之前調用它,那麼錯誤不會出現,因爲每個程序副本都會有它自己的ID很容易 - 這不是選項。在執行任何程序之前,需要攔截器進行自動化。希望解釋我以前沒有告訴過的所有東西:)

+0

實際上你需要在bean方法內打印出這個時間嗎?難道你不能簡單地用incterceptor方法打印出來嗎? – slwk 2014-12-04 10:25:49

+0

在大項目中有一個ID稍後需要用來創建一個SQL語句,在攔截器中獲得的ID,嘗試登錄後(這是我在普通攔截器中發生的情況)。如果登錄失敗,它不會返回任何內容,只是出現錯誤,否則會將用戶的ID寫入該變量以及另外3個變量。攔截器必須返回context.proceed(),所以我不能只返回變量。我希望這已經足夠清楚了:D – 2014-12-04 11:04:11

+0

我想你在攔截器功能中混合了一點業務邏輯。您是否真的有可能以不同於調用靜態攔截器字段的方式在您的業務方法中獲取此ID?例如。從會話中從數據庫中檢索它? – slwk 2014-12-04 11:42:11

回答

0

您可以使用@Produces進行記錄器創建,然後使用@Inject在您的類和攔截器中注入記錄器。這樣你應該記錄不同的時間。

+0

你可能誤會了我。記錄器沒有問題。由於MyTime變量是靜態的,每個人都有權訪問它,因此它被其他線程重寫。 – 2014-12-04 09:17:15