2011-08-22 12 views
5

में शामिल बिंदु बिंदु लागू किया जाता है मैं एक पहलू के साथ वसंत 3.0.5 का उपयोग कर रहा हूं।वसंत पहलू विफल रहता है जब नए धागे

@ आसपास के पहलू पूरी तरह से काम करता है। एओपी अभिव्यक्ति बीन्स के गुच्छा के इंटरफेस को लक्षित करती है।

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

कोई बड़ी बात नहीं:

पहलू से पहले और invokation के बाद कुछ तर्क निष्पादित करता है।

अब, मैं एक और पहलू बनाने की कोशिश कर रहा हूं जो एक अपवाद फेंकता है यदि अवरोधित विधि बहुत अधिक समय लेती है।

java.lang.RuntimeException: java.lang.IllegalStateException: नहीं MethodInvocation पाया: एक AOP कि चेक

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; 
} 

जब मैं केवल के साथ कोड निष्पादित इस पहलू मैं निम्न अपवाद प्राप्त आवेदन किया आमंत्रण प्रगति पर है, और एक्सपोज़ इनवोकेशनइंटरसेप्टर इंटरसेप्टर श्रृंखला में है।

Spring documentation से मैंने पढ़ा: "। कक्षा ExposeInvocationInterceptor

इंटरसेप्टर कि एक धागे की स्थानीय वस्तु के रूप में वर्तमान MethodInvocation को उजागर करता है"

तो ऐसा लगता है कि लक्ष्य खो गया है क्योंकि मैं मूल रूप से एक नया धागा शुरू करता हूं और नए धागे को थ्रेड स्थानीय तक पहुंच नहीं है। क्या इस समस्या को हल करने या बेहतर दृष्टिकोण का कोई तरीका है?

धन्यवाद

उत्तर

1

समाधान बहुत तुच्छ था। पहलू जो जांचता है कि एक विधि कितनी देर तक पहलुओं की "श्रृंखला" में अंतिम होनी चाहिए। मैंने इसे पहचाने जाने वाले अंतिम व्यक्ति को बनाने के लिए पहलू पर @Order एनोटेशन का उपयोग किया है।

यह चाल है।

यदि पहलू को अंतिम रूप देने के लिए अंतिम नहीं है, तो नया थ्रेड ExposeInvocationInterceptor कक्षा वाले थ्रेडलोकल चर तक पहुंचने में सक्षम नहीं है।

0

आप किसी अन्य धागे से वर्तमान धागा दखल अगर pjp.proceed() कॉल रुकावट के लिए उत्तरदायी है की कोशिश कर सकते। जैसे अपने पहलू लगता है:

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

जहां टोकनेवाला वर्ग की तरह कुछ होगा:

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

कोशिश करेंगे! धन्यवाद –

संबंधित मुद्दे