2011-08-22 26 views
5

Tôi đang sử dụng Spring 3.0.5 với một khía cạnh Xung quanh.Spring Aspect thất bại khi tham gia điểm được gọi trong chủ đề mới

Khía cạnh @Around hoạt động hoàn hảo. Biểu thức AOP nhắm vào các giao diện của một nhóm các bean.

Khía cạnh thực hiện một số logic trước và sau khi invokation:

@Around(...) 
    public Object monitor(ProceedingJoinPoint pjp) throws Throwable { 
     // some code 
     Obj o = pjp.proceed(); 
     // some code 
    } 

Không vấn đề lớn.

Bây giờ, tôi đang cố tạo một khía cạnh khác để ném ngoại lệ nếu phương pháp bị chặn mất quá nhiều thời gian.

private static ExecutorService executor = Executors.newCachedThreadPool(); 

@Around(...) 
public Object monitor(ProceedingJoinPoint pjp) throws Throwable { 

Object obj = null; 

Callable<Object> task = new Callable<Object>() { 
    public Object call() { 
     return pjp.proceed(); 
    } 
}; 
Future<Object> future = executor.submit(task); 
try { 
    obj = future.get(timeout, TimeUnit.MILLISECONDS); 
} catch (TimeoutException ex) { 
    ... 
} catch (InterruptedException e) { 
    // we ignore this one... 
} catch (ExecutionException e) { 
    throw e.getCause(); // rethrow any exception raised by the invoked method 
} finally { 
    future.cancel(true); // may or may not desire this 
} 

return obj; 
} 

Khi tôi thực thi mã chỉ với khía cạnh này áp dụng Tôi có được ngoại lệ sau đây:

java.lang.RuntimeException: java.lang.IllegalStateException: Không MethodInvocation tìm thấy: Kiểm tra xem một AOP yêu cầu đang được tiến hành, và ExposeInvocationInterceptor nằm trong chuỗi chặn.

Từ Spring documentation tôi đọc: "Lớp ExposeInvocationInterceptor

Interceptor mà cho thấy nhiều MethodInvocation hiện như một đối tượng thread-địa phương"

Vì vậy, có vẻ như mục tiêu đã bị mất vì tôi về cơ bản bắt đầu một chuỗi mới và chuỗi mới không có quyền truy cập vào chuỗi địa phương. Có cách nào để giải quyết vấn đề này hay cách tiếp cận tốt hơn không?

Cảm ơn

Trả lời

1

Giải pháp là khá tầm thường. Aspect kiểm tra xem một phương thức mất bao lâu phải là phương pháp cuối cùng trong "chuỗi" các khía cạnh. Tôi đã sử dụng chú thích @Order trên Aspect để làm cho chú thích cuối cùng được thực hiện.

Điều đó đã làm điều đó.

Nếu Aspect không phải là cuối cùng được thực thi, Thread mới không thể truy cập biến ThreadLocal có chứa lớp ExposeInvocationInterceptor.

0

Bạn có thể thử làm gián đoạn các chủ đề hiện tại từ thread khác, nếu cuộc gọi pjp.proceed() là tuân theo sự gián đoạn. Ví dụ. khía cạnh của bạn trông giống như:

new Interrupter(Thread.currentThread()).start(); 
    // Following call will get interrupted if it takes too long 
    try { 
     return pjp.proceed(); 
    } catch (InterruptedException ex) { 
     // do something? 
    } 

nơi lớp Interrupter sẽ là một cái gì đó như:

static class Interrupter extends Thread { 

    private final Thread other; 

    Interrupter(final Thread other) { 
     this.other = other; 
    } 

    @Override 
    public void run() { 
     try { 
      Thread.sleep(500); // or whatever your timeout is 
     } catch (final InterruptedException e) { 
      e.printStackTrace(); 
     } 
     if (other.isAlive()) { 
      other.interrupt(); 
     } 
    } 
} 
+0

Sẽ thử điều đó! Cảm ơn –

Các vấn đề liên quan