6 Replies Latest reply on Jan 17, 2013 11:25 AM by umbreak

    How does a @EJB dependency injection work on a Stateless Bean? Will that injected class behave like an instance variable in that stateless session bean?

    adheep

      Hi guys,

       

      I have this question on the latest  version EJB 3.1 has the "@EJB" annotation which is used for the dependency injection.

      I have two stateless session bean and a singleton bean

       

      @Stateless
      public class PrimaryStatelessBean {
      
           @EJB
           SecodaryStatelessBean secondaryStatelessBean;
      
           @EJB
           SimpleSingletonBean simpleSingletonBean;
      
           public String processRequest ( ) {
                
                .....
                secondaryStatelessBean.getValue();
                simpleSingletonBean.getAnotherValue();
                ....
           }
      
      }
      

      How does the @EJB annotation work, will the injected class behave like an Instance variable of the PrimaryStatelssBean ?

        • 1. Re: How does a @EJB dependency injection work on a Stateless Bean? Will that injected class behave like an instance variable in that stateless session bean?
          viggo.navarsete

          Yes, you're correct! Whenever a new instance of PrimaryStatelessBean is created by the EJB container (and since it's a stateless annotated bean, you will get a new one for each request), then you will get injected a new instance of SecondaryStatelessBean (since it's most likely also a stateless annotated bean, based on your naming convention), and you will get access to the *one instance* of SimpleSingletonBean that has been created by the EJB container (since it's a Singleton annotated bean).

          • 2. Re: How does a @EJB dependency injection work on a Stateless Bean? Will that injected class behave like an instance variable in that stateless session bean?
            adheep

            @Viggo Navarsete: Thanks for your reply.

             

            But this brings me an another question, Supose if a method in "PrimaryStatelessBean" is annotated with REST will it work the same way, because we will not create a new instance for the PrimaryStatelessBean if it is invoked as a RESTful webservice.

            @Stateless
            public class PrimaryStatelessBean {
             
                 @EJB
                 SecodaryStatelessBean secondaryStatelessBean;
             
                 @EJB
                 SimpleSingletonBean simpleSingletonBean;
                  
                      @POST
                      @Path("/requestService")
                      @Consumes("*/*")
                      @Produces("*/*")
                 public String processRequest ( ) {
                      
                      .....
                      
            
                      secondaryStatelessBean.getValue();   //(After making a first request) When I make another request will i get the same value "Testing Value" here
            
                      simpleSingletonBean.getAnotherValue();
            
            
            
            
                      secondaryStatelessBean.setValue("Testing Value");   // set values for secondaryStatelessBean in the first request
                      ....
            
                      
            
            
                 }
            
            }
            

            On the first request to my to "processRequest" service using REST, if i change the value of a member variable in SecondaryStatelessBean by

             

            secondaryStatelessBean.setValue("Testing Value");   // set values for secondaryStatelessBean in the first request
            

             

            and on the next request, will i get the value "Testing Value" here ?

             

            secondaryStatelessBean.getValue();   //(After making a first request) When I make another request will i get the same value "Testing Value" here
            
            • 3. Re: How does a @EJB dependency injection work on a Stateless Bean? Will that injected class behave like an instance variable in that stateless session bean?
              viggo.navarsete

              No, the "Testing Value" will not be there on the second request! But, it shouldn't be too difficult for you to actually test it, or? But I would assume that if you set a value on the simpleSingletonBean on the first request, then it would still be there on the second request!

              • 4. Re: How does a @EJB dependency injection work on a Stateless Bean? Will that injected class behave like an instance variable in that stateless session bean?
                adheep

                Viggo Navarsete wrote:

                 

                No, the "Testing Value" will not be there on the second request! But, it shouldn't be too difficult for you to actually test it, or? But I would assume that if you set a value on the simpleSingletonBean on the first request, then it would still be there on the second request!

                I did try an example and below are the codes

                 

                PrimaryStatelessBean.java

                package com.sample.rest.service;
                
                import javax.ejb.EJB;
                import javax.ejb.Stateless;
                import javax.ws.rs.GET;
                import javax.ws.rs.Path;
                import javax.ws.rs.Produces;
                import javax.ws.rs.core.MediaType;
                import com.test.ejb.SecondaryStatelessBean;
                import com.test.ejb.SampleSingletonBean;
                
                @Stateless
                @Path("/services")
                public class PrimaryStatelessBean{
                
                     @EJB
                    SecondaryStatelessBean primaryStatelessBean;
                
                    @EJB
                    SampleSingletonBean sampleSingletonBean;
                
                    @GET
                    @Path("/getValue")
                    @Produces("text/xml")
                    public String getValue(){
                
                        //To get initial value
                        System.out.println("Before Setting Value::" + primaryStatelessBean.getMessage());
                
                        //To get Request count
                        System.out.println("Request Count:: " + sampleSingletonBean.getCount());  
                
                        //set value for the Bean
                        primaryStatelessBean.setMessage("Hi Buddy Cool!!");
                
                        //After setting value
                        System.out.println("After Setting Value::" + primaryStatelessBean.getMessage());
                
                        return "<MESSAGE>"+primaryStatelessBean.getMessage()+"</MESSAGE>";
                
                    }
                


                SecondaryStatelessBean.java

                package com.test.ejb;
                
                import javax.ejb.Stateless;
                
                @Stateless
                public class SecondaryStatelessBean {
                
                    String mMessage = "No Value is set";
                
                    public String getMessage() {
                        return mMessage;
                    }
                
                    public void setMessage(String message) {
                        this.mMessage = message;
                    }
                
                }
                


                SampleSingletonBean.java

                package com.test.ejb;
                
                import javax.ejb.Singleton;
                
                @Singleton
                public class SampleSingletonBean {
                
                    long mRequestCount = 0;
                
                    public long getCount() {
                
                        return mRequestCount + 1;
                
                    }
                
                }
                


                Result:

                 

                First Request:
                
                
                [Server:Web-Node1] 17:52:15,872 INFO  [stdout] (http--192.168.5.157-8280-1) Before Setting Value::No Value is set
                [Server:Web-Node1] 17:52:15,872 INFO  [stdout] (http--192.168.5.157-8280-1) RequestCount:: 1
                [Server:Web-Node1] 17:52:15,873 INFO  [stdout] (http--192.168.5.157-8280-1) After Setting Value::Hi Buddy Cool!!
                
                Second Request:
                
                
                [Server:Web-Node1] 17:53:19,489 INFO  [stdout] (http--192.168.5.157-8280-1) Before Setting Value::Hi Buddy Cool!!
                [Server:Web-Node1] 17:52:15,872 INFO  [stdout] (http--192.168.5.157-8280-1) RequestCount:: 1
                [Server:Web-Node1] 17:53:19,490 INFO  [stdout] (http--192.168.5.157-8280-1) After Setting Value::Hi Buddy Cool!!
                
                Third Request:
                
                
                [Server:Web-Node1] 17:53:19,489 INFO  [stdout] (http--192.168.5.157-8280-1) Before Setting Value::Hi Buddy Cool!!
                [Server:Web-Node1] 17:52:15,872 INFO  [stdout] (http--192.168.5.157-8280-1) RequestCount:: 1
                [Server:Web-Node1] 17:53:19,490 INFO  [stdout] (http--192.168.5.157-8280-1) After Setting Value::Hi Buddy Cool!!
                
                and on random Request again  I get
                
                
                [Server:Web-Node1] 17:55:30,517 INFO  [stdout] (http--192.168.5.157-8280-1) Before Setting Value::No Value is set
                [Server:Web-Node1] 17:55:30,517 INFO  [stdout] (http--192.168.5.157-8280-1) RequestCount:: 1
                [Server:Web-Node1] 17:55:30,517 INFO  [stdout] (http--192.168.5.157-8280-1) After Setting Value::Hi Buddy Cool!!
                
                


                Is there any thing that i'm missing here?

                • 5. Re: How does a @EJB dependency injection work on a Stateless Bean? Will that injected class behave like an instance variable in that stateless session bean?
                  dlofthouse

                  Is there any thing that i'm missing here?

                   

                  You never assign a new value to mRequestCount so it will always return 0+1. You are probably looking for ++mRequestCount.

                  • 6. Re: How does a @EJB dependency injection work on a Stateless Bean? Will that injected class behave like an instance variable in that stateless session bean?
                    umbreak

                    And in reference to the class SecondaryStatelessBean, this is an example of how a Stateless class should NOT be used.

                     

                    From JavaEnterPrise Beans:

                    The procedure runs from beginning to end, finally returning the result. Once the invocation completes, nothing about the data that was manipulated or the details of the request is available. When finished servicing a method invocation, an SLSB instance may be reused as the target for a new request.

                     

                    Bypassing conversational state doesn’t mean that a stateless session bean can’t have instance variables or maintain any kind of internal state. Nothing prevents you from keeping a variable that tracks the number of times a bean instance has been called or a variable that saves data for debugging. However, it is important to remember that this state may never be visible to a client. The caller of an SLSB can’t assume that the same bean instance will service all of its requests. Instance variables may have different values in different bean instances, so their state is likely to appear to change randomly as stateless session beans are swapped from one client to another. Therefore, anything you reference in instance variables should be generic and not leaked out through the API.

                    As a summary: SLSB are reusable. The container guarantees concurrency having a pool of instances, so NEVER two users will consume the same instance at the same time. The container choose one instance among all the available instances on the pool an serves it to the client.

                     

                    For this reason, in the example, the value retrieved in primaryStatelessBean.getMessage() is the one set in the previous call. If you perform the test with ab (Apache Benchmark) with concurrency, you would see that different instances are created and that different values would be shown.