2011-12-22 22 views
10

मैं आवेदन स्तर (विशेष रूप से, एक संदेश संचालित बीन) के आस-पास कुछ गुणों को पारित करने के लिए EJBContext का उपयोग करने की योजना बना रहा हूं, जो कि जीवनशैली कॉलबैक को सीधे इंजेक्शन या पारित पैरामीटर (ग्रहण लिंक्स में सत्र श्रोता, इकाई लाइफसाइक्ल कॉलबैक इत्यादि) नहीं हो सकता है। ।), और वह कॉलबैक JNDI के माध्यम से EJBContext प्राप्त कर रहा है।EJBContext getContextData का उपयोग करना - क्या यह सुरक्षित है?

यह काम पर प्रतीत होता है लेकिन क्या कोई छुपा गेटचास है, जैसे थ्रेड सुरक्षा या ऑब्जेक्ट जीवनकाल जो मुझे याद आ रही है? (मान लें पारित किया जा रहा संपत्ति के मूल्य स्ट्रिंग की तरह अडिग या लांग है।)

नमूना सेम कोड

@MessageDriven 
public class MDB implements MessageListener { 
    private @Resource MessageDrivenContext context; 

    public void onMessage(Message m) { 
     context.getContextData().put("property", "value"); 
    } 
} 

तो कॉलबैक कि EJBContext

public void callback() { 
    InitialContext ic = new InitialContext(); 
    EJBContext context = (EJBContext) ic.lookup("java:comp/EJBContext"); 
    String value = (String) context.getContextData().get("property"); 
} 

मैं क्या सोच रहा हूँ है की खपत, क्या मुझे यकीन है कि contextData मानचित्र सामग्री केवल वर्तमान आवेषण/धागे के लिए दृश्यमान हैं? दूसरे शब्दों में, यदि दो धागे callback विधि एक साथ चल रहे हैं, और दोनों JNDI से EJBContext देख रहे हैं, तो वे वास्तव में contextData मानचित्र सामग्री प्राप्त कर रहे हैं?

और, कैसे करता है कि वास्तव में काम - EJBContext JNDI देखने वास्तव में एक ThreadLocal की तरह संरचना अंततः के चारों ओर एक आवरण वस्तु से दिया जाता है?

उत्तर

8

मैं सामान्य रूप में लगता है कि विधि का अनुबंध सक्षम करने के लिए है interceptors + webservice संदर्भ और सेम के बीच संचार। इसलिए संदर्भ सभी कोड, तक उपलब्ध होना चाहिए जब तक कि कोई नया आमंत्रण संदर्भ बनाया गया हो। जैसे कि यह बिल्कुल थ्रेड-सुरक्षित होना चाहिए।

InvocationContext वस्तु मेटाडाटा कि इंटरसेप्टर तरीकों मंगलाचरण श्रृंखला के व्यवहार को नियंत्रित करने के लिए सक्षम बनाता है प्रदान करता है:

धारा EJB 3.1 कल्पना की 12.6 निम्नलिखित कहते हैं। संदर्भित डेटा अलग-अलग व्यावसायिक विधि आमंत्रण या जीवन चक्र कॉलबैक ईवेंट में तेज़ नहीं है। इंटरसेप्टर एक वेब सेवा समाप्ति बिंदु पर मंगलाचरण, नक्शे getContextData द्वारा वापस की वजह से लागू कर रहे हैं

इसके अलावा JAX-WS MessageContext हो जाएगा, getContextData विधि 4.3.3 में वर्णित है:

GetContextData विधि किसी व्यवसाय विधि, जीवन चक्र कॉलबैक विधि या टाइमआउट विधि को अपने आमंत्रण से जुड़े किसी भी इंटरसेप्टर/वेबसार्सेस संदर्भ को पुनर्प्राप्त करने में सक्षम बनाता है।

वास्तविक क्रियान्वयन के संदर्भ में, JBoss के रूप में निम्नलिखित है:

public Map<String, Object> getContextData() { 
    return CurrentInvocationContext.get().getContextData(); 
} 

कहाँ CurrentInvocationContext एक thread-local linked list के आधार पर पॉप और वर्तमान मंगलाचरण संदर्भ पुश करने के लिए एक ढेर का उपयोग करता है।

org.jboss.ejb3.context.CurrentInvocationContext देखें। आमंत्रण संदर्भ केवल आलसी HashMap बनाता है, जैसा कि org.jboss.ejb3.interceptor.InvocationContextImpl

ग्लासफ़िश कुछ समान करता है। यह gets an invocation है, और यह from an invocation manager करता है, जो पॉप के लिए thread-local array list पर आधारित एक स्टैक का उपयोग करता है और इन आमंत्रण संदर्भों को फिर से दबाता है।

ग्लासफिश कार्यान्वयन के लिए JavaDoc यहाँ विशेष रूप से दिलचस्प है:

यह चर भंडार TLS एक ArrayList। ArrayList में घटक इन्वोकेशन ऑब्जेक्ट्स हैं जो इस धागे पर इनवोकेशन के ढेर का प्रतिनिधित्व करते हैं। ArrayList तक पहुंच को सिंक्रनाइज़ करने की आवश्यकता नहीं है क्योंकि प्रत्येक थ्रेड का अपना ऐरेलिस्ट होता है।

बस के रूप में JBoss के रूप में, ग्लासफिश भी lazily एक सरल HashMap बनाता है, com.sun.ejb.EjbInvocation में इस मामले में। ग्लासफ़िश मामले में दिलचस्प यह है कि स्रोत सेवा में webservice कनेक्शन को स्थानांतरित करना आसान है।

9

मैं EJBContext से संबंधित अपने प्रश्नों के साथ सीधे आपकी मदद नहीं कर सकता, क्योंकि getContextData विधि जेईई 6 में जोड़ा गया था, इसके बारे में अभी भी बहुत अधिक दस्तावेज नहीं है।

हालांकि TransactionSynchronizationRegistry का उपयोग करके ईजेबी, इंटरसेप्टर और लाइफसाइक्ल कॉलबैक के बीच प्रासंगिक डेटा पारित करने का एक और तरीका है। अवधारणा और नमूना कोड इस blog post by Adam Bien में पाया जा सकता है।

javax.transaction.TransactionSynchronizationRegistry एक मानचित्र की तरह संरचना रखती है और एक सौदे के अंदर राज्य पारित करने के लिए इस्तेमाल किया जा सकता। यह पुराने जे 2 ईई 1.4 दिनों से पूरी तरह से काम करता है और धागा-स्वतंत्र है।

क्योंकि एक इंटरसेप्टर को उसी लेनदेन में सर्विसफैक के रूप में निष्पादित किया जाता है, इसलिए राज्य को @AroundInvoke विधि में भी सेट किया जा सकता है। TransactionSynchronizationRegistry (टीएसआर) सीधे एक इंटरसेप्टर में इंजेक्शन किया जा सकता है।

उदाहरण वहाँ TransactionSynchronizationRegistry प्राप्त करने के लिए @Resource इंजेक्शन का उपयोग करता है, लेकिन यह भी InitialContext इस तरह से देखा जा सकता है:

public static TransactionSynchronizationRegistry lookupTransactionSynchronizationRegistry() throws NamingException { 
    InitialContext ic = new InitialContext(); 
    return (TransactionSynchronizationRegistry)ic.lookup("java:comp/TransactionSynchronizationRegistry"); 
} 
+1

अच्छा सुझाव। 'EJBContext' के लिए मैं जिस पैटर्न का उपयोग कर रहा हूं वह लगभग समान है - एक ही स्थान पर '@ संसाधन' के साथ इंजेक्शन, मानचित्र में ऑब्जेक्ट्स डालना, और फिर कहीं और जेएनडीआई में देखना। तो सवाल यह है कि 'EJBContext' ऑब्जेक्ट 'ट्रांज़ेक्शन सिंक्रनाइज़ेशन रजिस्ट्री' – wrschneider

+1

ट्रांज़ेक्शन सिंक्रनाइज़ेशन रजिस्ट्री की एक सीमा है: इसे हमेशा एक लेनदेन की आवश्यकता होती है, लेकिन कुछ मामलों में लेनदेन के बिना सूचनाओं को प्रसारित करना आवश्यक है – obe6

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