स्टेटलेस और स्टेटफुल एंटरप्राइज जावा बीन्स


93

मैं जावा ईई 6 ट्यूटोरियल के माध्यम से जा रहा हूं और मैं स्टेटलेस और स्टेटफुल सत्र बीन्स के बीच के अंतर को समझने की कोशिश कर रहा हूं। यदि स्टेटलेस सेशन बीन्स मेथड कॉल के बीच अपने राज्य को बरकरार नहीं रखता है, तो मेरा प्रोग्राम इस तरह से क्यों काम कर रहा है?

package mybeans;

import javax.ejb.LocalBean;
import javax.ejb.Stateless;

@LocalBean
@Stateless
public class MyBean {

    private int number = 0;

    public int getNumber() {
        return number;
    }

    public void increment() {
        this.number++;
    }
}

ग्राहक

import java.io.IOException;
import javax.ejb.EJB;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.WebServlet;
import mybeans.MyBean;
import java.io.PrintWriter;

@WebServlet(name = "ServletClient", urlPatterns = { "/ServletClient" })
public class ServletClient extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @EJB
    MyBean mybean;

    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {

        PrintWriter out = response.getWriter();
        mybean.increment();
        out.println(mybean.getNumber());
    }

}

मैं हर बार 0 पाने के लिए getNumber की उम्मीद कर रहा था, लेकिन यह 1 लौट रहा है और मेरे ब्राउज़र में सर्वलेट के पुनः लोड करने से यह अधिक बढ़ जाता है। समस्या मेरी समझ में यह है कि पुस्तकालयों या एप्लिकेशन सर्वर के साथ स्टेटलेस सत्र सेम कैसे काम करता है और नहीं। क्या कोई मुझे एक सरल सत्रीय दुनिया का उदाहरण दे सकता है जो एक स्टेटलेस सेशन बीन का उदाहरण है जब आप इसे स्टेटफुल में बदलते हैं तो अलग तरह से व्यवहार करते हैं?


6
संबंधित: stackoverflow.com/questions/8887140/… यह उत्तर शायद समझने में सरल है। ध्यान दें कि सर्वलेट्स मूल रूप से स्कोप किए गए एप्लिकेशन होते हैं (केवल 1 सर्वलेट इंस्टेंस होता है, जो सभी साझा अनुरोधों / सत्रों में साझा / पुन: उपयोग किया जाता है।
BalusC

नमस्ते, आप पहले वेतन वृद्धि करते हैं, और फिर मूल्य प्राप्त करते हैं .... इसलिए आप 0.
rzur2004

मैं सिर्फ यह पूछने के लिए धन्यवाद देना चाहता हूं, यह इस समय मेरी समस्या का समाधान करता है। मैं यह नहीं पूछ सकता था कि बेहतर
kholofelo मालोमा

जवाबों:


93

महत्वपूर्ण अंतर निजी सदस्य चर नहीं है, लेकिन एक विशेष उपयोगकर्ता के साथ राज्य को संबद्ध करना (सोचें "खरीदारी की टोकरी")।

स्टेटफुल सेशन बीन का स्टेटफुल पीस सर्वलेट्स में सेशन की तरह है। स्टेटफुल सेशन बीन्स आपके ऐप को वेब क्लाइंट न होने पर भी उस सेशन को करने की अनुमति देता है। जब एप्लिकेशन सर्वर ऑब्जेक्ट पूल से एक स्टेटलेस सेशन बीन प्राप्त करता है, तो यह जानता है कि इसका उपयोग किसी भी अनुरोध को पूरा करने के लिए किया जा सकता है, क्योंकि यह किसी विशेष उपयोगकर्ता से जुड़ा नहीं है।

एक स्टेटफुल सेशन बीन को पहले इस्तेमाल करने वाले यूजर को देना होता है, क्योंकि उनकी शॉपिंग कार्ट की जानकारी उन्हें ही पता होनी चाहिए। ऐप सर्वर यह सुनिश्चित करता है कि ऐसा हो। कल्पना करें कि यदि आप खरीदारी शुरू कर सकते हैं तो आपका ऐप कितना लोकप्रिय होगा और जब मैं साथ आया तो ऐप सर्वर ने आपका स्टेटफुल सेशन बीन दिया!

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


क्या आप एक टिप्पणी में एक स्पष्ट जवाब दे सकते हैं? हमेशा इस उदाहरण में स्टेटलेस बीन क्यों मूल्य रखता है और हर बार इसे बढ़ाता है? क्योंकि केवल एक उपयोगकर्ता है?
२१:५३ पर धनुषाकार

2
काउंटर उपयोगकर्ताओं की संख्या के बावजूद वृद्धि करेगा। तो अगर user1 अंदर आता है और काउंटर को 1 तक बढ़ाता है और साथ ही user2 अंदर आता है और इसे बढ़ाता है, तो मान 2 होगा। यह वास्तव में दिखाना चाहिए कि user1 में 1 है और user2 में 1 है (यदि वह जो आप करने का इरादा कर रहे हैं। शॉपिंग कार्ट उदाहरण के रूप में ऊपर)।
कृष्ण

137

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

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

एक और चीज़। यदि आप एसएफएसबी का उपयोग कर रहे हैं, तो आपको उन्हें उन वर्गों में इंजेक्ट करने से बचना चाहिए जो प्रकृति में मल्टीथ्रेडेड हैं, जैसे कि सर्वलेट्स और जेएसएफ प्रबंधित बीन्स (आप नहीं चाहते कि यह सभी ग्राहकों द्वारा साझा किया जाए)। यदि आप अपने वेब एप्लिकेशन में एसएफएसबी का उपयोग करना चाहते हैं, तो आपको जेएनडीआई लुकअप करने और HttpSessionभविष्य की गतिविधि के लिए ऑब्जेक्ट में लौटे ईजेबी उदाहरण को स्टोर करने की आवश्यकता है । ऐसा कुछ:

try {
    InitialContext ctx = new InitialContext();
    myStateful = (MyStateful)ctx.lookup("java:comp/env/MyStatefulBean");
    session.setAttribute("my_stateful", myStateful);
} catch (Exception e) {
    // exception handling
}

स्पष्ट के लिए धन्यवाद। जब मैं क्लाइंट के लिए स्टैंडअलोन कमांड लाइन प्रोग्राम का उपयोग करता हूं, तो अंतर देखना स्पष्ट है।
स्टेनली केली

टिप्पणियों के लिए धन्यवाद, वे अधिक ज्ञानवर्धक हैं। पहले अपनी सार परिभाषा दें, फिर प्रत्येक स्थिति के लिए कुछ उपयोग मामलों को निर्दिष्ट करें, और फिर कुछ नुकसानों को इंगित करें। महान +1
आर्थर

क्या ईजेबी 3.1 के लिए इंजेक्शन लगाने वाला हिस्सा बाहर निकल जाता है?
जैकट्रेड्स

7
@ पास्कल अगर "स्टेटफुल सेशन बीन्स (एसएफएसबी) एक क्लाइंट को अपने पूरे जीवन के लिए समर्पित है", यही क्षमता एसएफएसबी में बनी है, तो फिर उन्हें HttpSession ऑब्जेक्ट पर स्टोर करने की आवश्यकता क्यों है?
user1169587

2
अगर हमें पहले से ही 'सेशन' करना है तो सत्र में स्टेटफुल बीन की आवश्यकता क्यों है? इस तरह हम हर वस्तु को सेशन कर सकते हैं। व्याख्या करें pls
Georgy Gobozov

18

इस संदर्भ में स्टेटलेस और स्टेटफुल का मतलब यह नहीं है कि आप क्या उम्मीद कर सकते हैं।

EJBs के साथ राजकीय व्यवहार से तात्पर्य है कि मैं संवादी स्थिति को क्या कहता हूं । क्लासिक उदाहरण एक उड़ान बुकिंग है। यदि इसमें तीन चरण होते हैं:

  • रिजर्व सीट
  • क्रेडिट कार्ड चार्ज करें
  • टिकट जारी करें

कल्पना कीजिए कि उनमें से प्रत्येक एक सत्र बीन के लिए एक विधि कॉल है। एक स्टेटफुल सेशन बीन इस तरह की बातचीत को बनाए रख सकता है ताकि यह याद रहे कि कॉल के बीच क्या होता है।

स्टेटलेस सत्र बीन्स में संवादात्मक स्थिति के लिए ऐसी क्षमता नहीं होती है।

एक सत्र बीन (स्टेटलेस या स्टेटफुल) के अंदर वैश्विक चर पूरी तरह से कुछ और हैं। स्टेटफुल सेशन बीन्स में सेम का एक पूल होगा (चूंकि एक सेम एक समय में केवल एक बातचीत में इस्तेमाल किया जा सकता है) जबकि स्टेटलेस सेशन बीन्स में अक्सर केवल एक ही उदाहरण होगा, जो वैश्विक चर काम करेगा, लेकिन मुझे नहीं लगता है यह जरूरी है।


5

दो प्रमुख प्रकार के सत्र बीन्स के बीच प्रमुख अंतर हैं:

स्टेटलेस बीन्स

  1. स्टेटलेस सेशन बीन्स वे हैं जिनके क्लाइंट के साथ कोई वार्तालाप नहीं है। इस कारण से वे वस्तुओं का एक पूल बना सकते हैं जिसका उपयोग कई ग्राहकों के साथ बातचीत करने के लिए किया जा सकता है।
  2. प्रदर्शन बुद्धिमान स्टेटलेस बीन्स बेहतर हैं क्योंकि उनके पास प्रति ग्राहक राज्य नहीं हैं।
  3. वे संभाल कर सकते हैं कई लोगों के अनुरोध कई समानांतर में ग्राहकों।

स्टेटफुल बीन्स

  1. स्टेटफुल सेशन बीन्स एक समय में कई क्लाइंट्स के साथ बातचीत एल स्टेट को बनाए रख सकते हैं और टास्क को क्लाइंट्स के बीच शेयर नहीं किया जाता है।
  2. सत्र पूरा होने के बाद राज्य को बरकरार नहीं रखा जाता है।
  3. कंटेनर भविष्य में उपयोग के लिए राज्य को बासी अवस्था के रूप में क्रमबद्ध और संग्रहीत कर सकता है । यह एप्लिकेशन सर्वर के संसाधनों को बचाने और बीन विफलताओं का समर्थन करने के लिए किया जाता है।

4

यह बात इसलिए है क्योंकि कंटेनर में पूल में केवल एक बीन का उदाहरण है जिसे सभी कॉल के लिए पुन: उपयोग किया जा रहा है। यदि आप क्लाइंट्स को समानांतर में चलाते हैं तो आपको एक अलग परिणाम दिखाई देगा क्योंकि कंटेनर पूल में अधिक सेम इंस्टेंस बनाएगा।


4

इसके अच्छे उत्तर हैं। मैं छोटा सा जवाब जोड़ना चाहूंगा। स्टेटलेस बीन का इस्तेमाल किसी भी क्लाइंट डेटा को रखने के लिए नहीं किया जाना चाहिए। इसका उपयोग "एक शॉट में किए जाने वाले कार्यों या प्रक्रियाओं को मॉडल करने के लिए" किया जाना चाहिए।


4

अच्छा प्रश्न,

इस कोड को आज़माएं (MyBean Stateful / Stateless को बदलें।):

import javax.ejb.LocalBean;
import javax.ejb.Stateful;
import javax.ejb.Stateless;

@LocalBean 
@Stateless 
public class MyBean {

    private int number = 0;

    public int getNumber() {
        return number;
    }

    public void increment() {
        this.number++;
    }
}

Servlet_1

 import java.io.IOException;
    import javax.ejb.EJB;
    import javax.servlet.*;
    import javax.servlet.http.*;
    import javax.servlet.annotation.WebServlet;

    import java.io.PrintWriter;

    @WebServlet(name = "ServletClient", urlPatterns = { "/ServletClient" })
    public class ServletClient extends HttpServlet {

        private static final long serialVersionUID = 1L;

        @EJB
        MyBean mybean;

        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

            PrintWriter out = response.getWriter();
            mybean.increment();
            out.println(mybean.getNumber());
        }

    }

Servlet_2

import java.io.IOException;
import javax.ejb.EJB;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.WebServlet;

import java.io.PrintWriter;

@WebServlet(name = "NewServletClient", urlPatterns = { "/NewServletClient" })
public class NewServletClient extends HttpServlet {

    private static final long serialVersionUID = 1L;

    @EJB
    MyBean mybean;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        PrintWriter out = response.getWriter();
        mybean.increment();
        out.println(mybean.getNumber());
    }

}

मामला: MyBean - @ स्टेटलेस

http: // localhost: 8080 / MYServletDemo / ServletClient

1

http: // localhost: 8080 / MYServletDemo / ServletClient

2

http: // localhost: 8080 / MYServletDemo_war_exploded / newServletClient

3

http: // localhost: 8080 / MYServletDemo / ServletClient

4

मामला: MyBean - @ स्टेटफुल

http: // localhost: 8080 / MYServletDemo / ServletClient

1

http: // localhost: 8080 / MYServletDemo / ServletClient

2

http: // localhost: 8080 / MYServletDemo / newServletClient

1

http: // localhost: 8080 / MYServletDemo / ServletClient

3


1
हाँ, यह बात है और यह काम करता है! बहुत आसान स्पष्टीकरण, धन्यवाद!
नेस्काइक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.