2010-07-09 6 views
19

मुझे आश्चर्य है कि कोई भी सलाह दे सकता है: मेरे पास एक परिदृश्य है जहां क्वार्ट्ज द्वारा निर्धारित एक निर्धारित नौकरी हर घंटे ऑब्जेक्ट्स की सरणीसूची अपडेट करेगी।जावा सर्वलेट संदर्भ में वैश्विक ऑब्जेक्ट कैसे प्राप्त करें और सेट करें

लेकिन मुझे टॉमकैट द्वारा बनाए गए सभी सत्रों के लिए दृश्यमान वस्तुओं की इस सरणी सूची की आवश्यकता है। तो मैं जो सोच रहा हूं वह यह है कि मैं इस वस्तु को क्वार्ट्ज नौकरी से कहीं भी हर घंटे लिखता हूं जो चलता है ताकि प्रत्येक सत्र इसे एक्सेस कर सके।

क्या कोई यह कह सकता है कि यह कैसे हासिल किया जा सकता है? मैं क्वार्ट्ज नौकरी से सर्वलेट संदर्भ में लिखे गए वस्तु के बारे में सोच रहा था? विकल्प प्रत्येक सत्र डेटाबेस डेटाबेस से ऑब्जेक्ट्स की सरणी सूची को पॉप्युलेट कर रहा है।

धन्यवाद

श्री मॉर्गन।

+0

इस अन्य एसओएफ पोस्ट में भी इस चुनौती का एक उपयोगी चर्चा है: http://stackoverflow.com/questions/10276041/retrieve-servletcontext-reference-in-quartz-scheduler – Steve

+0

स्प्रिंग से एक की तरह वैश्विक अनुप्रयोग संदर्भ ? – PSyLoCKe

उत्तर

12

हां, मैं सूची को ServletContext में एक एप्लिकेशन-स्कोप्ड विशेषता के रूप में संग्रहीत करता हूं। इसके बजाय डेटाबेस से डेटा खींचना शायद कम कुशल है, क्योंकि आप केवल हर घंटे सूची अपडेट कर रहे हैं। क्वार्ट्ज कार्य को ServletContext ऑब्जेक्ट का संदर्भ देने के लिए ServletContextListener बनाना आवश्यक हो सकता है। ServletContext केवल जावाईई-संबंधित कक्षाओं जैसे Servlets और श्रोताओं से पुनर्प्राप्त किया जा सकता है।

संपादित करें: ServletContextListener में, जब आप नौकरी बनाते हैं, तो आप इसे जॉबडेटा मैप में जोड़कर नौकरी में भेज सकते हैं।

public class MyServletContextListener implements ServletContextListener{ 
    public void contextInitialized(ServletContextEvent event){ 
    ArrayList list = new ArrayList(); 

    //add to ServletContext 
    event.getServletContext().setAttribute("list", list); 

    JobDataMap map = new JobDataMap(); 
    map.put("list", list); 
    JobDetail job = new JobDetail(..., MyJob.class); 
    job.setJobDataMap(map); 
    //execute job 
    } 

    public void contextDestroyed(ServletContextEvent event){} 
} 

//Quartz job 
public class MyJob implements Job{ 
    public void execute(JobExecutionContext context){ 
    ArrayList list = (ArrayList)context.getMergedJobDataMap().get("list"); 
    //... 
    } 
} 
+0

तो आप जो कह रहे हैं वह यह है कि मेरे पास एक श्रोता है जिसमें ऑब्जेक्ट को पॉप्युलेट करने के लिए एक विधि है; यह श्रोता तब चलता है जब संदर्भ प्रारंभ होता है और ऑब्जेक्ट को पॉप्युलेट करता है। फिर क्वार्ट्ज नौकरी श्रोता के माध्यम से ऑब्जेक्ट पर हर घंटे चलने पर प्राप्त कर सकती है? –

+1

किसी अन्य उत्तर से कोई टिप्पणी देखकर, ऐसा लगता है कि आपके पास पहले से ही ServletContextListener है जो क्वार्ट्ज कार्य शुरू करता है? आप क्या कर सकते हैं श्रोता में सूची बनाते हैं, फिर सूची को ServletContext में एक विशेषता के रूप में जोड़ें, फिर उस सूची को कार्य में पास करें। फिर आप 'ServletContext # getAttribute()' को कॉल करके अपने वेब एप्लिकेशन में कहीं भी सूची तक पहुंच सकते हैं। उदाहरण के लिए, एक सर्वलेट में, आप '(ArrayList) getServletContext() प्राप्त करेंगे। GetAttribute ("list") '। सुनिश्चित करें कि आप अपनी सूची को सही तरीके से सिंक्रनाइज़ करते हैं ताकि आप इसे एक ही समय में पढ़/लिख नहीं रहे हों। – Michael

+0

यह अच्छा लगता है लेकिन एक अपवाद के साथ। मुझे यकीन नहीं है कि 'फिर उस कार्य को उसी सूची में पास करें' संभव है जिस तरह से क्वार्ट्ज के शेड्यूल नियंत्रक द्वारा नौकरियां जमा की जाती हैं। –

0

ठीक है, यदि आप स्थिर फ़ील्ड का उपयोग करते हैं तो वे एक ही कक्षा लोडर द्वारा लोड की गई सभी कक्षाओं के लिए दृश्यमान होंगे। मुझे लगता है कि कम से कम एक ऐप के सर्लेट को क्वालीफाइंग समाप्त करना चाहिए। हालांकि, यह स्वीकार्य रूप से गंदा है।

एक वस्तु जिसे परिभाषित और गारंटी दी जाती है (अधिक) वैश्विक ServletContext है। यह एक आवेदन के हिस्से को बनाने वाले सभी सर्वलेट्स के बीच साझा किया जाता है, यानी web.xml से लोड किया गया है। put और get ServletContext के लिए कॉल हैं जो आपको इसे मानचित्र के रूप में अनिवार्य रूप से इलाज करने की अनुमति देते हैं।

इसके अलावा, आपको एक टोमकैट सर्वर के अंदर सभी वेब ऐप्स के लिए सामान्य कक्षाएं मिलनी होंगी। टॉमकैट लोडर के साथ बहुत सारे काम करता है, और मुझे लगता है कि विभिन्न वेब ऐप्स में अलग लोडर होंगे। आप अपने आप को एक वर्ग लिखकर और उस वर्ग को टॉमकैट के common या shared निर्देशिकाओं में रखकर प्राप्त कर सकते हैं। अगर मैं this description सही ढंग से समझता हूं, तो उन वर्गों को सभी वेब ऐप्स पर, एक बार उपलब्ध कराया जाएगा।

अंत में, एक एकल टोमकैट सर्वर की सीमा से परे, आपको JVMs के बीच संचार करने के लिए कुछ टीसीपी/आईपी आधारित तंत्र की आवश्यकता होगी। लेकिन जैसा कि मैंने आपका प्रश्न समझा, यह आवश्यक नहीं होना चाहिए।

+0

लेकिन क्या आप सर्वलेट के बाहर ServletContext तक पहुंच सकते हैं? क्वार्ट्ज नौकरी का उल्लेख है वह एक है जो उनके इंटरफ़ेस को लागू करता है। हालांकि मैं सांख्यिकी के साथ कक्षा का उपयोग करने के लिए तैयार हूं। –

+0

हम्म। क्या यह क्वार्ट्ज नौकरी टोमकैट के अंदर एक सर्वलेट या फ़िल्टर के रूप में चल रही है? यदि हां, तो हाँ। अगर इसे बाहरी जेवीएम में निकाल दिया जा रहा है तो उसे टॉमकैट के दिमाग में परेशानी होगी। [इस क्वार्ट्ज दस्तावेज़] को देख रहे हैं (http://www.quartz-scheduler.org/docs/cookbook/ServletInitScheduler.html), ऐसा लगता है कि क्वार्ट्ज आपके ऐप के अंदर होगा, हालांकि, और सभी ठीक होना चाहिए। –

+0

कम से कम क्वार्ट्ज आपके ServletContext तक पहुंच प्राप्त करता है (वर्णित दोनों स्थितियों में)। मुझे उम्मीद है कि क्वार्ट्ज के पास उस संदर्भ को अपने एपीआई उपयोगकर्ताओं के लिए भी सुलभ बनाने के लिए अच्छी समझ है। –

1

आप मान संग्रहीत करने के लिए EhCache की तरह, कुछ कैशिंग समाधान की कोशिश, और उन्हें हर घंटे अपडेट कर सकते हैं। यह समवर्ती मुद्दों को संभालेगा। कैश ऑब्जेक्ट को ServletContext

क्वार्ट्ज नौकरी से ServletContext पर लिखने का एक अच्छा तरीका है श्रोताओं को आपके काम पर पंजीकृत करना है जो बदले गए मूल्य के बारे में अधिसूचित हो। उदाहरण के लिए:

public class JobListener { 
    public void updateValue(Object newValue); 
} 

public class ServletContextCacheJobListener implements JobListener { 
    private ServletContext ctx; 
    public ServletContextJobListener(ServletContext ctx) { 
     this.ctx = ctx; 
    } 

    public void updateValue(Object newValue) { 
      Cache cache = (Cache) ctx.getAttribute("cache"); 
      cache.update("yourKey", newValue); 
    } 
} 

अपनी नौकरी एक List<JobListener> होगा और जब आप काम अनुसूची, आप ठोस श्रोता का दृष्टांत और नौकरी में जोड़ें।

+0

यकीन नहीं है कि मैं समझता हूं कि आप कहां से आ रहे हैं। क्या आप स्पष्ट कर सकते हो? क्या आप कह रहे हैं कि मेरे क्वार्ट्ज नौकरी में जॉबलिस्टर या सर्वलेट कॉन्टेक्स्ट कैश जॉब लिस्टनर की एक सूची होनी चाहिए? यदि उत्तरार्द्ध, संभवतः मैं एक समय में सूची को एक तत्व सेट करूँगा? –

+0

पर्यवेक्षक (श्रोता) पैटर्न के बारे में पढ़ें। और 'ServletContextCacheJobListener' एक' जॉबलिस्टर 'है क्योंकि यह इसे लागू करता है। तो कोई फर्क नहीं पड़ता है – Bozho