跟小弟我StepByStep学FLEX教程-Demo12之FLEX和Spring整合

跟我StepByStep学FLEX教程------Demo12之FLEX和Spring整合

跟我StepByStep学FLEX教程------FLEX和Spring整合 

 

 

说明:该文系作者原创,请勿商用或者用于论文发表,转载必须经作者同意并且注明出处。

 

 

      这一讲是基于DEMO11,所以没有看DEMO11的读者请一定阅读,因为Spring的整合是基于J2EE的。

      因为要和Spring整合,所以先简单讲一下Spring(如果要对Spring没有接触过的读者也没关系,按照讲的内容也能做,但是这样没啥实际意义,所以要对本讲要有所收获,必须对Spring有一定的理解)。

      首先下载Spring,作者选择的Spring版本Spring Framework2.0.8。可以在官网

http://www.springsource.org/下载,也可以去网络搜索都可以。


跟小弟我StepByStep学FLEX教程-Demo12之FLEX和Spring整合
 

       

      Spring对于J2EE来说,读者应该都非常熟悉,Spring以其轻量级的应用迅速的普及。

      对于Spring都需要了解的两个重要概念:

      1、控制反转(IoC=Inversion of  Control),依赖注入(DI=Dependency Injection);

           通俗一点来讲,比如作者在工作中经常使用的硬件设备:Dell620笔记本电脑、USB活动硬盘、aigo移动U盘。大家很熟悉吧。

           这三个设备都支持USB接口。需要将数据复制到外边的存储设备时,根据实际情况决定保存在U盘还是活动硬盘。

           相信这种操作大家司空见惯,而这也正是所谓依赖注入的一个典型例子。

           笔记本电脑和外围存储通过笔记本的USB接口相连,对于笔记本而言,只是将用户指定数据发送到USB接口,而这些数据何去何从,则由当前的USB设备决定。

      2、面向切面编程(AOP=Aspect Oriented Programming);

           这个大家可能觉得很抽象,其实现在大家应该都接触过,作者举两个例子:一个是WebWork框架的Intecepor就是AOP的应用;再一个大家更熟悉了,J2EE系统的Log4j的日志系统对于读者做的系统来说就是一个AOP。

           切面切面,就是一个截面,所做的程序不对现有系统进行破坏,但是随时可以打开关闭,这么理解就是很通俗通俗的理解了。

      这儿就简单提及一下,因为主要还是讲Flex和Spring的整合,读者就一步一步来做吧:)

     

            呵呵,大家觉得Spring的概念容易理解了吧:)

 

      Flex和Spring的整合

      1、将Spring的jar包拷贝到WEB-INF的lib下;(这个是必须的,否则怎么整合Spring)

      2、在web.xml中注册Spring,如下配置:

<!-- Spring configuration file (Not needed if you don't use Spring) -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>

<!-- Spring ContextLoaderListener (Not needed if you don't use Spring) -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

     3、增加SpringFactory.java,代码如下:

package com.samples.factories;

import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;

import flex.messaging.FactoryInstance;
import flex.messaging.FlexFactory;
import flex.messaging.config.ConfigMap;
import flex.messaging.services.ServiceException;

/**
 * This interface is implemented by factory components which provide
 * instances to the flex messaging framework.  To configure flex data services
 * to use this factory, add the following lines to your services-config.xml
 * file (located in the WEB-INF/flex directory of your web application).
 *
 * &lt;factories&gt;
 *     &lt;factory id="spring" class="flex.samples.factories.SpringFactory" /&gt;
 *  &lt;/factories&gt;
 *
 * You also must configure the web application to use spring and must copy the spring.jar
 * file into your WEB-INF/lib directory.  To configure your app server to use spring,
 * you add the following lines to your WEB-INF/web.xml file:
 *
 *   &lt;context-param&gt;
 *        &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
 *        &lt;param-value&gt;/WEB-INF/applicationContext.xml&lt;/param-value&gt;
 *   &lt;/context-param&gt;
 *
 *   &lt;listener&gt;
 *       &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;
 *   &lt;/listener&gt;
 *
 * Then you put your spring bean configuration in WEB-INF/applicationContext.xml (as per the
 * line above).  For example:
 *
 *  &lt;?xml version="1.0" encoding="UTF-8"?&gt;
 *  &lt;!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"&gt;
 *  
 *  &lt;beans&gt;
 *    &lt;bean name="weatherBean" class="dev.weather.WeatherService" singleton="true"/&gt;
 *  &lt;/beans&gt;
 * 
 * Now you are ready to define a destination in flex that maps to this existing service.
 * To do this you'd add this to your WEB-INF/flex/remoting-config.xml:
 *
 *  &lt;destination id="WeatherService"&gt;
 *      &lt;properties&gt;
 *          &lt;factory&gt;spring&lt;/factory&gt;
 *          &lt;source&gt;weatherBean&lt;/source&gt;
 *      &lt;/properties&gt;
 *  &lt;/destination&gt;
 *
 * @author Jeff Vroom
 */
public class SpringFactory implements FlexFactory
{
    private static final String SOURCE = "source";

    /**
     * This method can be used to initialize the factory itself.  It is called with configuration
     * parameters from the factory tag which defines the id of the factory. 
     */
    public void initialize(String id, ConfigMap configMap) {}

    /**
     * This method is called when we initialize the definition of an instance
     * which will be looked up by this factory.  It should validate that
     * the properties supplied are valid to define an instance.
     * Any valid properties used for this configuration must be accessed to
     * avoid warnings about unused configuration elements.  If your factory
     * is only used for application scoped components, this method can simply
     * return a factory instance which delegates the creation of the component
     * to the FactoryInstance's lookup method.
     */
    public FactoryInstance createFactoryInstance(String id, ConfigMap properties)
    {
        SpringFactoryInstance instance = new SpringFactoryInstance(this, id, properties);
        instance.setSource(properties.getPropertyAsString(SOURCE, instance.getId()));
        System.out.println("SpringSpringSpring" + instance.toString());
        return instance;
    } // end method createFactoryInstance()

    /**
     * Returns the instance specified by the source
     * and properties arguments.  For the factory, this may mean
     * constructing a new instance, optionally registering it in some other
     * name space such as the session or JNDI, and then returning it
     * or it may mean creating a new instance and returning it.
     * This method is called for each request to operate on the
     * given item by the system so it should be relatively efficient.
     * <p>
     * If your factory does not support the scope property, it
     * report an error if scope is supplied in the properties
     * for this instance.
     */
    public Object lookup(FactoryInstance inst)
    {
        SpringFactoryInstance factoryInstance = (SpringFactoryInstance) inst;
        return factoryInstance.lookup();
    }


    static class SpringFactoryInstance extends FactoryInstance
    {
        SpringFactoryInstance(SpringFactory factory, String id, ConfigMap properties)
        {
            super(factory, id, properties);
        }


        public String toString()
        {
            return "SpringFactory instance for id=" + getId() + " source=" + getSource() + " scope=" + getScope();
        }

        public Object lookup()
        {
            ApplicationContext appContext = WebApplicationContextUtils.getWebApplicationContext(flex.messaging.FlexContext.getServletConfig().getServletContext());
            String beanName = getSource();

            try
            {
                return appContext.getBean(beanName);
            }
            catch (NoSuchBeanDefinitionException nexc)
            {
                ServiceException e = new ServiceException();
                String msg = "Spring service named '" + beanName + "' does not exist.";
                e.setMessage(msg);
                e.setRootCause(nexc);
                e.setDetails(msg);
                e.setCode("Server.Processing");
                throw e;
            }
            catch (BeansException bexc)
            {
                ServiceException e = new ServiceException();
                String msg = "Unable to create Spring service named '" + beanName + "' ";
                e.setMessage(msg);
                e.setRootCause(bexc);
                e.setDetails(msg);
                e.setCode("Server.Processing");
                throw e;
            }
        }
       
    }

}

     4、在services-config.xml中注册SpringFacotry,配置如下:

<factories>
     <factory id="spring" class="com.samples.factories.SpringFactory"/>
    </factories>

     5、接下来就要在applicationContext.mxl中注册helloJavaFlexBean,配置如下:

<bean id="helloJavaFlexBean" class="com.test.HelloJavaFlex">
    </bean>

     6、在remoting-config.xml中将SpringBean公开给Flex客户端,配置如下:

<destination id="helloJavaFlex"> 
    <properties>
      <factory>spring</factory>
      <source>helloJavaFlexBean</source>
     </properties>
    </destination>

    

     其它的代码都不用改动,运行一下,和Demo11的运行效果一样。

     读者可能会有疑问,增加了这么多配置,效果还和Demo11一样?

     1、这样的整合对于这种演示的小程序来说确实意义不大,但是大型项目这种Spring方式优点就非常明显了,因为和Flex客户端公开的是SpringBean的声明,所以无论底层逻辑甚至文件名称得改动,都不会有什么影响;

     2、Spring整合进来,就可以使用Spring很多特性了,呵呵,下个DEMO就会使用Spring的自带JDBCTemplate访问数据库;

     3、Spring的整合,对于Hibernate的整合提供了更大的便捷,这个也会在后边的DEMO中提及。

 

     下一讲对这这讲的Demo做个简单的解释。

1 楼 yxandy 2009-07-02  
非常好的东西,期待楼主讲讲flex与hibernate的lazy问题
2 楼 bxl994 2009-07-02  
加油啊,一直在关注楼主的东西,非常不错,讲的也比较详细,通俗易懂
3 楼 bxl994 2009-07-03  
楼主
<!-- Spring configuration file (Not needed if you don't use Spring) -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>

<!-- Spring ContextLoaderListener (Not needed if you don't use Spring) -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

这段加上报错啊,是不是拷贝jar包之后还要作一些spring的配置啊,这部分楼主是不是没有讲啊,因为我从来没接触过这些,需要从头开始一步一步的操作
4 楼 wangyisong 2009-07-06  
bxl994 写道
楼主
<!-- Spring configuration file (Not needed if you don't use Spring) -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>

<!-- Spring ContextLoaderListener (Not needed if you don't use Spring) -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

这段加上报错啊,是不是拷贝jar包之后还要作一些spring的配置啊,这部分楼主是不是没有讲啊,因为我从来没接触过这些,需要从头开始一步一步的操作

报什么错?你需要好拷贝Spring的jar包,还有需要配置applicationContext.xml
5 楼 drui1 2009-07-23  
读了你的文章真的受益颇丰!我没做过web开发,这个上个星期有个项目需要flex做interface,我用java链接后台数据库,可怎么也不能通信。看了好多实例配置,还是你的系列文章帮我完成了阶段目标。非常感谢!不知道如果我有问题,怎样能和你联系?只能发表留言么?希望能够得到你的回复!再次感谢!
6 楼 wangyisong 2009-07-23  
drui1 写道
读了你的文章真的受益颇丰!我没做过web开发,这个上个星期有个项目需要flex做interface,我用java链接后台数据库,可怎么也不能通信。看了好多实例配置,还是你的系列文章帮我完成了阶段目标。非常感谢!不知道如果我有问题,怎样能和你联系?只能发表留言么?希望能够得到你的回复!再次感谢!

感谢你的评价。发表留言或者使用javaeye短信都可以。不过有时候工作忙得时候如果回复不及时还请见谅。
7 楼 QQ87465335 2009-11-12  
<!-- Spring configuration file (Not needed if you don't use Spring) -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>

<!-- Spring ContextLoaderListener (Not needed if you don't use Spring) -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
这段加上就报错,web.xml文件就出错了
8 楼 QQ87465335 2009-11-12  
楼主,俺 是新手,你可以把要添加的Spring的包给我们列出来吗?
9 楼 fei56124174 2009-12-23  
QQ87465335 写道
<!-- Spring configuration file (Not needed if you don't use Spring) -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>

<!-- Spring ContextLoaderListener (Not needed if you don't use Spring) -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
这段加上就报错,web.xml文件就出错了

这是因为你把这段加到web.xml最后了,应该将<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>加到web.xml中原有的几个<context-param>一起。

楼主,对SpringFactory开不大明白,能否讲解一下
10 楼 domsn 2010-03-14  
楼主,你好,我更想知道,你是怎么知道这些的,方便的话,发到我邮箱行么,domsn.lee@foxmail.com
11 楼 zsq007 2010-03-17  
QQ87465335 写道
楼主,俺 是新手,你可以把要添加的Spring的包给我们列出来吗?

spring.jar
spring-aspects.jar
楼主的例子需要这两个包
12 楼 catlovefox 2010-04-22  
要添加的Spring的包给我们列出来吗?
domsn 写道
楼主,你好,我更想知道,你是怎么知道这些的,方便的话,发到我邮箱行么,domsn.lee@foxmail.com

这问题,真好玩~跟小弟我StepByStep学FLEX教程-Demo12之FLEX和Spring整合
13 楼 wx886104 2010-05-22  
从你这学到新东西,我回继续学习
14 楼 lzg128 2010-09-30  
楼主,你好!
   方便把案例代码发给我看下吗? 谢谢  790867479@qq.com
15 楼 hanyuxiao 2010-11-26  
王大大,我咨询一个问题,如果spring使用注解的方式,这样也可以吗?有没有更好的解决方案?