2. Configuration for Spring
Configuration for Spring
In order to initialize GDS/Tide for Spring and Hibernate, you must add granite.jar, granite-hibernate.jar, and granite-spring.jar to your WEB-INF/lib or in the lib directory of an ear. If you use another JPA provider, just replace the granite-hibernate.jar with the appropriate one from the GDS ditribution, for example granite-eclipselink.jar for EclipseLink.
In the case of ear packaging, it is important to put all libs in ear/lib and to make sure that no jar concerning JPA persistence is left in WEB-INF/lib.
Then you have to add the following configuration to your web.xml:
<web-app version="2.4" ...> ... <!-- Granite config context listener --> <listener> <listener-class>org.granite.config.GraniteConfigListener</listener-class> </listener> <!-- Spring --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:applicationContext.xml classpath*:applicationContextSecurity.xml </param-value> </context-param> <!-- Spring listener --> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <!-- Spring listener for web-scopes (request, session) --> <listener> <listener-class> org.springframework.web.context.request.RequestContextListener </listener-class> </listener> <filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- GDS AMF message filter --> <filter> <filter-name>AMFMessageFilter</filter-name> <filter-class>org.granite.messaging.webapp.AMFMessageFilter</filter-class> <!-- Uncomment (part of) this block if configs are not present at default locations. <init-param> <param-name>servicesConfigPath</param-name> <param-value>/WEB-INF/flex/services-config.xml</param-value> </init-param> <init-param> <param-name>graniteConfigPath</param-name> <param-value>/WEB-INF/granite/granite-config.xml</param-value> </init-param--> </filter> <filter-mapping> <filter-name>AMFMessageFilter</filter-name> <url-pattern>/graniteamf/*</url-pattern> </filter-mapping> <!-- GDS AMF Servlet --> <servlet> <servlet-name>AMFMessageServlet</servlet-name> <servlet-class>org.granite.messaging.webapp.AMFMessageServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> ... </web-app>
Of course the Spring configuration part can be changed to suit the needs of your application. This is just a basic example of a Spring application configuration. The important parts for Tide are the GDS servlets/filters.
Then you have to configure the specific Tide/Spring destination and service factory in service-config.xml:
<services-config> <services> <service id="granite-service" class="flex.messaging.services.RemotingService" messageTypes="flex.messaging.messages.RemotingMessage"> <!-- ! Use "tideSpringFactory" and "my-graniteamf" for "spring" destination (see ! below). The destination must be "spring" when using Tide with default ! configuration. !--> <destination id="spring"> <channels> <channel ref="my-graniteamf"/> </channels> <properties> <factory>tideSpringFactory</factory> <entityManagerFactoryBeanName> entityManagerFactory </entityManagerFactoryBeanName> </properties> </destination> </service> </services> <!-- ! Declare tideSpringFactory service factory. !--> <factories> <factory id="tideSpringFactory" class="org.granite.tide.spring.SpringServiceFactory" /> </factories> <!-- ! Declare my-graniteamf channel. !--> <channels> <channel-definition id="my-graniteamf" class="mx.messaging.channels.AMFChannel"> <endpoint uri="http://{server.name}:{server.port}/{context.root}/graniteamf/amf" class="flex.messaging.endpoints.AMFEndpoint"/> </channel-definition> </channels> </services-config>
Note that the destination named "spring" will be the one and only configuration needed for all remote component calls.
There is a little more configuration in granite-config.xml for Tide and Spring security integration:
<granite-config> <externalizers> <externalizer type="org.granite.hibernate.HibernateExternalizer"> <include annotated-with="javax.persistence.Entity"/> <include annotated-with="javax.persistence.MappedSuperclass"/> <include annotated-with="javax.persistence.Embeddable"/> </externalizer> ... </externalizers> ... <security type="org.granite.messaging.service.security.SpringSecurityService"/> <tide-components> <!-- List of component matchers, see 'Enabling components' section --> </tide-components> </granite-config>
This part is more simple with automatic scanning:
<granite-config scan="true"> <security type="org.granite.messaging.service.security.SpringSecurityService"/> <tide-components> <!-- List of component matchers, see 'Enabling components' section --> </tide-components> </granite-config>
Note that this default configuration will only allow lazy loading with JPA providers declared with a bean name entityManagerFactory. If you need to use a plain Hibernate Session, you will have to change the <entityManagerFactoryBeanName> in service-config.xml to <persistence-manager-bean-name>tidePersistenceManager</persistence-manager-bean-name> and add a few lines to applicationContext.xml that will declare a special Tide persistence manager that is able to handle the Hibernate API (assuming here that the Hibernate session factory is named sessionFactory):
<!-- All this AOP stuff just to ensure the Tide persistence manager will be transactional --> <aop:config> <aop:pointcut id="tidePersistenceManagerMethods" expression="execution(* org.granite.tide.ITidePersistenceManager.*(..))"/> <aop:advisor advice-ref="tidePersistenceManagerMethodsTxAdvice" pointcut-ref="tidePersistenceManagerMethods"/> </aop:config> <tx:advice id="tidePersistenceManagerMethodsTxAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="*" propagation="REQUIRED" read-only="true"/> </tx:attributes> </tx:advice> <bean id="tidePersistenceManager" class="org.granite.tide.hibernate.HibernateSessionManager" scope="request"> <constructor-arg> <ref bean="sessionFactory"/> </constructor-arg> </bean>
