1

I am trying to use session scope bean in spring mvc with following bean definitions

<bean id="test" class="com.gk.testScope.Test" scope="session">
<property name="name" value="mytest"></property>
<aop:scoped-proxy/>
</bean>

Code for controller

@Controller
public class MyController 
{


     @Autowired
     Test t;
     @RequestMapping(value="test1",method=RequestMethod.GET)
     public String test1(HttpServletRequest request) {

              System.out.println("name"+t.getName());
              request.getSession();
              return "test1";
      }

}

on running above code it prints mytest even before starting any session. Can some one explain what session scope doing here?

Gajendra Kumar
  • 908
  • 2
  • 12
  • 28

2 Answers2

0

Below line of code does not actually create session, it gets the session already created by the servlet container.

request.getSession();

Now comes the important stuff. Bit tricky to get at first if you are new to Spring scopes.

Injecting a singleton bean in another singleton bean is intuitive and makes sense. How about you want to inject a bean which is not Singleton into a Singleton bean? The injection should happen on demand right ? So to configure this, we cant directly inject the bean which is not singleton. We inject a proxy for a non singleton bean, which in turn gets a new bean injected on demand.

<aop:scoped-proxy/> 

The above tag helps create a new bean for every session(because the scope is "session") created on the server and injects in the controller on demand.

I am sure someone can explain in much simpler manner. Hope this helps.

R Sawant
  • 241
  • 1
  • 8
  • thanks for the reply ,request.getSession(); will return a new session if a session does not exists already [link](https://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/http/HttpServletRequest.html#getSession(boolean)) i understood that if one want to inject a non-singleton bean into a singleton bean then we need to add but that bean is associated with session? because i can access it without any session. – Gajendra Kumar Nov 29 '15 at 06:38
  • When servlet container creates a new session, Spring container gets that notification. Upon getting the notification, spring creates a session scoped bean. – R Sawant Nov 29 '15 at 06:43
0

The spring framework provides an inversion-of-control coding framework; that means you only has to concern your business logic and write down it as handler function, the spring framework would take care the rest of things and call your handler function.

For example, in a mvc spring framework, the http request handling, http session handling, the beans life-cycle management are all done in spring-framework and you only needed to write the "test1()" function that is called when client hit the URL "/test1".

When client start a HTTP session with spring web server, the framework will create a session scope, and all session scope beans will be created. When client sends a HTTP request, the framework will create a Request scope and all create request level scope beans.

Please see 6.5 Bean scopes from spring reference doc.

Houcheng
  • 2,674
  • 25
  • 32
  • I added a default constructor to Test class as: `public Test() { System.out.println("Object created"); }` on running my application it's printing object created at the time of startup without any HTTP SESSION it means object is created by the container on start up fine but how this object is associated with session like request.getSession() – Gajendra Kumar Nov 29 '15 at 09:24
  • 1
    The way Spring handles injecting non singleton beans into singleton is responsible for this. If you check startup logs, you will see two beans created of Test class. Those should be scopedTarget.Test#0 and Test#0 So when you call t.getName() in controller, you are actually invoking method on the proxy of Test. This proxy will get bean from session scope. Hope this will clear things up – R Sawant Nov 29 '15 at 12:10
  • 1
    The Test bean is created when container initialization, and this is why you see the output message. The association from "controller.t" to "T" instance is not established yet, as there is no session. You can only reference this association in the controller's member function; when call to t.getName(), it actually call a proxy object to find the real T instance and then call this instance's getName() function. – Houcheng Nov 30 '15 at 02:29