Search This Blog

Monday, 21 April 2014

Scopes and Dependencies

We saw an example of request and session scoped beans earlier. We saw how the ApplicationContext was used to get access to these beans. However making the code ApplicationContextAware may not be an acceptable solution.Who would be keen to have Spring's core classes intruding into the code ? Knowing this Spring does provide us with an alternative solutions involving AOP.
To test the same I decided to create another singleton Bean:
public class RequestManager {
   private RequestAudit crtRequestAudit;

   //setter getters
}
The requestManager class now has a dependency on the request scoped bean. I changed the Controller from the previous example to work with this class.
@Controller
public class DependencyController {

   @Autowired
   private RequestManager requestManager;

   @RequestMapping(value = "/simple.do", method = RequestMethod.GET)
   public String display(final HttpServletRequest request) {
      final RequestAudit requestAudit = (RequestAudit) this.requestManager.getCrtRequestAudit();
      System.out.println("RequestAudit in request { " + request + " } is " 
             + requestAudit.getRandomId() + ", created at "  
             + new SimpleDateFormat("yyyy-MM-dd, hh: mm :ss").format(requestAudit.getDate()));
      return "forward:/fwd.do";

   }
}
The code looks like any other Spring mvc code. The important point to keep in mind is that when we retrieve the dependency from the RequestManager we should be getting a Request Scoped bean. This part is indicated in the configuration:
<bean id="requestAudit" class="com.custom.request.RequestAudit" scope="request">
   <!-- instructs the container to proxy the surrounding bean -->
     <aop:scoped-proxy />
  </bean>

   <bean id="requestManager" class="com.custom.request.RequestManager">
      <property name="crtRequestAudit" ref="requestAudit" />
   </bean>
As seen here within our requestAudit bean we have used the scoped-proxy element. The Spring container creates a proxy for a bean that is marked up with the <aop:scoped-proxy/> element. Within the proxy lies the code to fetch the real object from the session or request scope. The container injects the proxy object into the requestManager bean. From within the proxy the calls are redirected to the actual bean. Running the above code would still print the log message:
2013-08-14 19:20:47 DEBUG DefaultListableBeanFactory:435 - 
Creating instance of bean 'scopedTarget.requestAudit'
...
RequestAudit in request { org.apache.catalina.connector.RequestFacade@1f1d038 } 
is n05s7eoq87j82oh96isiscjedn, created at 2013-08-14, 07: 20 :47
2013-08-14 19:20:47 TRACE HandlerMethod:135 - Method [display] returned [forward:/fwd.do]
The scoped /actual bean has a different name to our proxy bean.

No comments:

Post a Comment