2013-07-20 5 views
8

मेरे पास एक एकल-आवृत्ति वर्ग है, जो अपवाद मैपर लागू करता है। यह एक स्थिर वर्ग नहीं है, लेकिन यह एक वर्ग है जिसके लिए मुझे पता है कि केवल एक उदाहरण बनाया गया है (मैंने जांच की - निर्माता को केवल एक बार बुलाया जाता है)।जेएक्स-आरएस (जर्सी) अपवाद मैपर - @ कॉन्टैक्ट इंजेक्शन स्थिर/सिंगलटन वर्ग में - यह काम करता है, लेकिन क्यों?

मेरी कक्षा @Context HttpServletRequest का उपयोग करता है, और मैं स्पष्ट रूप से देख सकते हैं कि जब मेरे ExceptionMapper.toResponse() विधि कहा जाता है, @Context 'अनुरोध' पैरामीटर एक मूल्य जो एक अनुरोध के लिए प्रासंगिक है है जहां अपवाद फेंक दिया जाता है।

The doc says यह वास्तव में डिज़ाइन समर्थित सुविधा है और यह "प्रॉक्सी" का उपयोग करके किया जाता है।

मुझे आश्चर्य है कि यह वास्तव में कैसे कार्यान्वित किया जाता है - एक उदाहरण में एक साथ विभिन्न सदस्य परिवर्तनीय मूल्य कैसे हो सकते हैं?

धन्यवाद,
एजी

पुनश्च:

@Provider 
public class MyExceptionMapper implements ExceptionMapper<Exception> { 

    public MyExceptionMapper() { 
     System.out.println("CTOR!!"); 
    } 

    @Context HttpServletRequest req; 

    public static boolean done = false; 
    public Response toResponse(Exception ex) { 
     if (!done) { 
      done = true; 
      Thread.sleep(10000); 
     } 
     System.out.println(req.getRequestURI()); 
     return null; 
    } 
} 

मेरे बाकी हैंडलर विधि अपवाद फेंकता है तो जब मैं निम्नलिखित 2 अनुरोध "समानांतर में" अमल (नींद, यहाँ परीक्षण कोड है ऊपर यकीन है कि पहले एक पूरा नहीं हुआ है जब एक दूसरे के आता है और IMHO वन-एंड-केवल 'अनुरोध' फ़ील्ड को संशोधित करना चाहिए) बनाता है:

- http://localhost/app/one 
- http://localhost/app/two 

मेरा कार्यक्रम प्रिंट:

CTOR! 
http://localhost/app/one 
http://localhost/app/two 

उत्तर

5

प्रभाव आप का पालन इंजेक्शन HttpServletRequest वस्तु के लिए है को प्राप्त करने वास्तव में एक प्रॉक्सी वस्तु, असलीHttpServletRequest के लिए एक धागा अवगत प्रतिनिधि होने के लिए की सबसे सरल तकनीक। जब आप प्रतिनिधि पर विधियों को कॉल करते हैं, तो वे सब सही वास्तविक वस्तु (उदाहरण के लिए, एक थ्रेड स्थानीय चर के माध्यम से) देखते हैं और उस पर कॉल पास करते हैं। यह रणनीति सही होने के लिए अपेक्षाकृत सरल है, और क्योंकि यह एक इंटरफेस है, हमें निश्चित रूप से फ़ील्ड एक्सेस के बारे में चिंता करने की ज़रूरत नहीं है (जो प्रॉक्सी के लिए काफी मुश्किल है)।

ऐसी प्रॉक्सी ऑब्जेक्ट बनाने के कुछ अलग तरीके हैं। विशेष रूप से, यह HttpServletRequest इंटरफ़ेस को सीधे कार्यान्वित करके किया जा सकता है, या इसे जावा general dynamic proxy mechanism (जो किसी भी इंटरफ़ेस के लिए प्रॉक्सी बना सकता है) के माध्यम से अधिक सामान्य रूप से किया जा सकता है। रनटाइम कोड पीढ़ी जैसी अन्य विस्तृत संभावनाएं हैं, लेकिन वे यहां अनावश्यक हैं। ओटीओएच, अगर HttpServletRequest सीधे लागू किया गया तो मुझे आश्चर्य नहीं होगा; यह एक जेएक्स-आरएस कार्यान्वयन के लिए कुछ हद तक महत्वपूर्ण वर्ग है ...

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