跟小弟我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/下载,也可以去网络搜索都可以。
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).
*
* <factories>
* <factory id="spring" class="flex.samples.factories.SpringFactory" />
* </factories>
*
* 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:
*
* <context-param>
* <param-name>contextConfigLocation</param-name>
* <param-value>/WEB-INF/applicationContext.xml</param-value>
* </context-param>
*
* <listener>
* <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
* </listener>
*
* Then you put your spring bean configuration in WEB-INF/applicationContext.xml (as per the
* line above). For example:
*
* <?xml version="1.0" encoding="UTF-8"?>
* <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
*
* <beans>
* <bean name="weatherBean" class="dev.weather.WeatherService" singleton="true"/>
* </beans>
*
* 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:
*
* <destination id="WeatherService">
* <properties>
* <factory>spring</factory>
* <source>weatherBean</source>
* </properties>
* </destination>
*
* @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做个简单的解释。
<!-- 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 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
感谢你的评价。发表留言或者使用javaeye短信都可以。不过有时候工作忙得时候如果回复不及时还请见谅。
<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文件就出错了
<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开不大明白,能否讲解一下
spring.jar
spring-aspects.jar
楼主的例子需要这两个包
这问题,真好玩~
方便把案例代码发给我看下吗? 谢谢 790867479@qq.com