[Logo] Enterprise Client Community
  [Search] Search   [Recent Topics] Recent Topics   [Members]  Member Listing   [Groups] Back to home page 
[Register] Register / 
[Login] Login 
Cookbook Spring DI  XML
Forum Index -> Development - Code Snippets
Author Message
mreich

Power User
[Avatar]

Joined: 30/01/2009 08:34:23
Messages: 744
Offline

Hi community,

I want to share my expiriences with the integration of the Spring DI into the CaptainCasa framework!

First you have to download the relevant jar libraries from SpringSource.org

Put the relevant jars into your projects wecontent/WEB-INF/lib directory and add it to your classpath (normally the lib directory is already added to the classpath).

Create the applicationContext.xml file in your sources directory (normally src).

Add Spring info to your web.xml file:
Code:
 <context-param>
   <param-name>contextConfigLocation</param-name>
   <param-value>/WEB-INF/classes/applicationContext.xml</param-value>
 </context-param>
 
 <listener>
   <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>
 

To access the beans throw your business logic is no problem, you have to configure your applicationContext.xml so the relevant object instances get injected by the framework.

To get access to the spring context in Cpt.Casa UI classes I use following work around:

Create a class to get the ApplicationContext from the FacesContext:
Code:
 public class Context {
     public static ApplicationContext getInstance() {
         FacesContext context= FacesContext.getCurrentInstance();
         
         ServletContext servletContext = (ServletContext)context.getExternalContext().getContext();
         return WebApplicationContextUtils.getWebApplicationContext(servletContext);       
     }
 }
 

Then create a layer class for my business logic services (see example below). Important is the public static factory method getFromApplicationContext(ctx).
Code:
 public final class LogicLayer {
     
     ...
     
     public static LogicLayer getFromApplicationContext(ApplicationContext ctx) {
         return (LogicLayer) ctx.getBean("logicLayer");
     }
 }
 

The name of the bean "logicLayer" is defined in the applicationContext.xml:
Code:
 <bean id="logicLayer" class="logic.LogicLayer">
     ...
 </bean>
 

Create your own implementation of class WorkpageDispatcher, where you integrate the access methods to the beans:
Code:
 /*
  * The dispatcher is references in faces-config.xml. When changing the package
  * of the dispatcher - please also update the faces-config.xml link!
  */
 @SuppressWarnings("serial")
 public class Dispatcher extends WorkpageDispatcher
 {
     /*
      * This method needs to be implemented - is serves tools (e.g. Layout
      * Editor) to find out which objects are exposed by this dispatcher.
      */
     public static DispatcherInfo getStaticDispatcherInfo()
     {
         return new DispatcherInfo(Dispatcher.class);
     }
     
     /**
      * Returns the expression under which the dispatcher can be reached.
      */
     @Override
     protected String getRootExpression()
     {
         return "#{d}";
     }
     
     protected b
     public LogicLayer getLogicLayer() {    return logicLayer; }
     public void setLogicLayer(LogicLayer logicLayer) { this.logicLayer = logicLayer; }
 }
 

Create your own WorkpageDispatchedBean where you cast to your Dispatcher implementation and get the reference through getOwningDispatcher():
Code:
 public class MyWorkpageDispatchedBean extends WorkpageDispatchedBean
 {
     public MyWorkpageDispatchedBean(IWorkpageDispatcher dispatcher) {
         super(dispatcher);
     }
         
     @Override
     public Dispatcher getOwningDispatcher() {
         return (Dispatcher) super.getOwningDispatcher();
     }    
 
     // ------------------------------------------------------------------------
     // logic access
     // ------------------------------------------------------------------------
     protected LogicLayer getLogic() {
         return getOwningDispatcher().getLogicLayer();
     }   
 }
 

In the managed bean you now can access the logic layer:
Code:
 public class TestUI extends MyWorkpageDispatchedBean implements
         Serializable {
 
     private final LogicLayer logicLayer = getLogic();
     ...
 }
 

Maybe you have your own servlets running within the servlet you can access the Spring context the following way:
Code:
 ServletContext context = getServletContext();
 WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(context);
 LogicLayer logicLayer = LogicLayer.getFromApplicationContext(context);
 


This works fine for me. I also tried to directly inject the instances into the Dispatcher(managed bean) with the Spring class DelegatingVariableResolver, but I didn't get it working by now.

The way I tried:

Added DelegatingVariableResolver to faces-config.xml:
Code:
 <application>  
     <variable-resolver>  
         org.springframework.web.jsf.DelegatingVariableResolver  
     </variable-resolver>  
 </application>
 

Added dispatcher bean to applicationContext.xml:
Code:
 <bean id="d" class="Dispatcher" scope="session">
     <property name="logicLayer">
         <ref bean="logicLayer" />
     </property> 
 </bean> 
 

Just mentioned if somebody has the muse to research further
[WWW]
mreich

Power User
[Avatar]

Joined: 30/01/2009 08:34:23
Messages: 744
Offline

Normally Spring is configured to create just one instance per bean. This instance is returned by getBean method of the Spring context class.

In my special case I needed a kind of Dictionary class which includes session relevant data (e.g. user that is logged on ...).
In the standard scenario described above, there would be just one instance, so there would be some nice surprises in your application

But there's a simple solution, do change the scope of the bean to session, which means, that for every new session a separate instance is created.

Just add the property scope="session" to your bean definition. If you've wired this class already to other beans, you also have to switch on CGLIB proxy creation, which is also easily done, by adding the attribute <aop:scoped-proxy/>

My bean definition:
Code:
<?xml version="1.0" encoding="UTF-8"?>
 <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns: xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xsi:schemaLocation="
 <a href="http://www.springframework.org/schema/beans" target="_blank" rel="nofollow">http://www.springframework.org/schema/beans</a> <a href="http://www.springframework.org/schema/beans/spring-beans-2.0.xsd" target="_blank" rel="nofollow">http://www.springframework.org/schema/beans/spring-beans-2.0.xsd</a>
 <a href="http://www.springframework.org/schema/aop" target="_blank" rel="nofollow">http://www.springframework.org/schema/aop</a> <a href="http://www.springframework.org/schema/aop/spring-aop-2.0.xsd" target="_blank" rel="nofollow">http://www.springframework.org/schema/aop/spring-aop-2.0.xsd</a>">
 
     <bean id="dictionaryService" class="trimatrix.utils.Dictionary"
         abstract="false" lazy-init="default" autowire="default" 
         dependency-check="default" scope="session">       
         <!-- this next element effects the proxying of the surrounding bean -->
         <aop:scoped-proxy/>         
     </bean>
 </beans>
[WWW]
Anonymous



GJLipX <a href="http://kiezoosvoxjy.com/">kiezoosvoxjy</a>, ivgvozhzkyvz, [link=http://odsgtpdfumaz.com/]odsgtpdfumaz[/link], http://mxlqynecfawl.com/
 
Forum Index -> Development - Code Snippets
Go to:   
Powered by JForum 2.1.6 © JForum Team