क्या फैक्ट्री या प्रॉक्सी बनाना संभव है जो तय कर सकता है कि थ्रेड चल रहा है (वेब) अनुरोध या पृष्ठभूमि-प्रक्रिया (यानी शेड्यूलर) और उसके बाद उस जानकारी के आधार पर, यह एक सत्र बीन या प्रोटोटाइप बीन बनाता है?वसंत: संदर्भ (सत्र/वेब या स्थानीय धागा/पृष्ठभूमि प्रक्रिया) पर निर्भर बीन इंजेक्ट करें
उदाहरण (छद्म स्प्रिंग config :)
<bean id="userInfoSession" scope="session" />
<bean id="userInfoStatic" scope="prototype" />
<bean id="currentUserInfoFactory" />
<bean id="someService" class="...">
<property name="userInfo" ref="currentUserInfoFactory.getCurrentUserInfo()" />
</bean>
मुझे आशा है कि यह मेरे सवाल को समझने के लिए आसान बना देता है ...
मेरे समाधान
यह देर से करने के लिए करने के लिए कभी नहीं अपने प्रश्न अपडेट करें;)। मैंने इसे क्लाइंट सत्र के दो अलग-अलग उदाहरणों, एक सत्र स्कोप्ड क्लाइंट सत्र और एक सिंगलटन स्कोप्ड सत्र के साथ हल किया। दोनों सामान्य सेम हैं।
<bean id="sessionScopedClientSession" class="com.company.product.session.SessionScopedClientSession" scope="session">
<aop:scoped-proxy />
</bean>
<bean id="singletonScopedClientSession" class="com.company.product.session.SingletonScopedClientSession" />
<bean id="clientSession" class="com.company.product.session.ClientSession">
<property name="sessionScopedClientSessionBeanName" value="sessionScopedClientSession" />
<property name="singletonScopedClientSessionBeanName" value="singletonScopedClientSession" />
</bean>
ClientSession फिर अगर सिंगलटन या सत्र दायरे तय करेगा:
private IClientSession getSessionAwareClientData() {
String beanName = (isInSessionContext() ? sessionScopedClientSessionBeanName : singletonScopedClientSessionBeanName);
return (IClientSession) ApplicationContextProvider.getApplicationContext().getBean(beanName);
}
कहाँ सत्र प्रकार इस के माध्यम से इकट्ठा किया जा सकता है:
private boolean isInSessionContext() {
return RequestContextHolder.getRequestAttributes() != null;
}
सभी वर्गों एक इंटरफेस IClientSession कहा जाता है को लागू। सिंगलटनस्कोप्ड और सत्र स्कोप्ड बीन्स दोनों बेस क्लाइंट सत्र से फैले हुए हैं जहां कार्यान्वयन पाया जाता है। अब
@Resource
private ClientSession clientSession;
...
public void doSomething() {
Long orgId = clientSession.getSomethingFromSession();
}
अगर हम एक कदम आगे हम सत्र के लिए एक एम्यूलेटर की तरह कुछ लिख सकते हैं जाना:
हर सेवा तो ग्राहक सत्र यानी उपयोग कर सकते हैं। यह सिंगलटन सत्र क्लाइंट सत्र (जो किसी अनुरोध के संदर्भ में नहीं है) को प्रारंभ करके किया जा सकता है। अब सभी सेवाओं को एक ही clientSession उपयोग कर सकते हैं और हम अभी भी "अनुकरण" कर सकते हैं एक उपयोगकर्ता यानी:
clientSessionEmulator.startEmulateUser(testUser);
try {
service.doSomething();
} finally {
clientSessionEmulator.stopEmulation();
}
एक और सलाह: SingletonScoped clientSession उदाहरण में सूत्रण के बारे में ध्यान रखना! वाह, मैंने सोचा कि मैं इसे कम लाइनों के साथ कर सकता हूं;) यदि आप इस दृष्टिकोण के बारे में अधिक जानना चाहते हैं तो मुझसे संपर्क करने में संकोच न करें।
मैं इसे आज़माउंगा। कभी-कभी सबसे सरल समाधान सबसे अच्छा होता है और यदि यह काम करता है, तो यह साफ क्यों नहीं है? कुछ अन्य समाधान? –
@ फ्रैंक: कोड जो 'RequestContextHolder' का उपयोग करता है, आमतौर पर परीक्षण करना मुश्किल होता है। इसी कारण से, इसे निराश किया जाना चाहिए। – skaffman