用Annotation方式发布Flex-Bds服务

本文介绍了一种使用Spring框架简化BDS服务发布的实现方法。通过自定义FlexRemotingServiceProxyExporter类,可以自动扫描并注册带有BdsService注解的Bean作为BDS服务。
[quote]Spring最近(08-12-16)发布了支持BDS的类库:spring-flex-1.0.0.M1.jar,但还是没有提供Annotation发布方式,于是趁周末无聊的时间,让它简化到底吧(至少在官方的Anno没有发布出来之前)。
[/quote]
这是Spring提供的BDS服务导出配置:

<!-- Bootstraps and exposes the BlazeDS MessageBroker -->
<bean id="mySpringManagedMessageBroker"
class="org.springframework.flex.messaging.MessageBrokerFactoryBean" />

<!-- Implementation of ProductService using Spring's SimpleJdbcTemplate -->
<bean id="productService" class="flex.samples.product.JdbcProductService" >
<constructor-arg ref="dataSource"/>
</bean>

<!-- Expose the productService bean for BlazeDS remoting -->
<bean id="product"
class="org.springframework.flex.messaging.remoting.FlexRemotingServiceExporter">
<property name="messageBroker" ref="mySpringManagedMessageBroker"/>
<property name="service" ref="productService"/>
</bean>

注册请求服务

<!-- Maps request paths at /messagebroker to the BlazeDS MessageBroker -->
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<value>
/messagebroker/*=mySpringManagedMessageBroker
</value>
</property>
</bean>

<!-- Dispatches requests mapped to a MessageBroker -->
<bean class="org.springframework.flex.messaging.servlet.MessageBrokerHandlerAdapter"/>

服务导出的重点就在FlexRemotingServiceExporter,更具它的原理,重构一个ProxyExporter

public class FlexRemotingServiceProxyExporter implements InitializingBean, ResourceLoaderAware {
private static final Logger logger = Logger.getLogger(FlexRemotingServiceProxyExporter.class);

/**
* Flex 消息发布器
*/
private MessageBroker messageBroker;

/**
* BdsService集合
*/
private Map<String, Object> bdsServiceMap = new HashMap<String, Object>();

private List<RemotingDestination> rdList = new ArrayList<RemotingDestination>();

public void setMessageBroker(MessageBroker messageBroker) {
this.messageBroker = messageBroker;
}

public void afterPropertiesSet() throws Exception {
Assert.notNull(messageBroker, "The 'messageBroker' property is required.");

RemotingService remotingService = (RemotingService) messageBroker
.getServiceByType(RemotingService.class.getName());
Assert.notNull(remotingService, "Could not find a proper RemotingService in the Flex MessageBroker.");

for (String serviceId : bdsServiceMap.keySet()) {
RemotingDestination destination = (RemotingDestination) remotingService
.createDestination(serviceId);
rdList.add(destination);

FlexFactory factory = new FlexFactoryInstance(bdsServiceMap.get(serviceId));

destination.setFactory(factory);
destination.start();

Assert.isInstanceOf(JavaAdapter.class, destination.getAdapter(),
"Spring beans exported as a RemotingDestination require a JavaAdapter.");
}
}

public void setResourceLoader(ResourceLoader resourceLoader) {
if (resourceLoader instanceof XmlWebApplicationContext) {
XmlWebApplicationContext context = (XmlWebApplicationContext) resourceLoader;
String[] names = context.getParent().getBeanDefinitionNames();

for (String name : names) {

Object bean = context.getParent().getBean(name);
BdsService bdsService = bean.getClass().getAnnotation(BdsService.class);
if (bdsService == null) {
continue;
}

bdsServiceMap.put(bdsService.serviceName(), bean);

logger.info("Export bdsService: " + bdsService.serviceName());
}
}
}

}


FlexFactoryInstance:

public class FlexFactoryInstance implements FlexFactory {
private Object bean;

public FlexFactoryInstance(Object bean) {
this.bean = bean;
}

public FactoryInstance createFactoryInstance(String id, ConfigMap properties) {
return new ServiceFactoryInstance(this, id, properties);
}

public Object lookup(FactoryInstance instanceInfo) {
throw new UnsupportedOperationException("FlexFactory.lookup");
}

public void initialize(String id, ConfigMap configMap) {
// No-op
}

public final class ServiceFactoryInstance extends FactoryInstance {
public ServiceFactoryInstance(FlexFactory factory, String id, ConfigMap properties) {
super(factory, id, properties);
}

@Override
public Object lookup() {
return bean;
}
}
}


BdsService

@Target(TYPE)
@Retention(RUNTIME)
public @interface BdsService {
/**
* 服务名称
* @return
*/
String serviceName() default "";
}

大功告成,下面是使用SAMPLE
创建bdsServiceContext.xml,在WEB.XML中定义(注意,该xml只能在WEB.XML中引入,如果跟其他的webController配置放置在一起,在SPRING加载时,因为有限读取Adapter的原则,其他的controller配置——包括Hessian的服务导出都会失效):

web.xml

<servlet>
<servlet-name>flexDispatcherServlert</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:nbf/config/spring/flexContext.xml
</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>flexDispatcherServlert</servlet-name>
<url-pattern>/messagebroker/*</url-pattern>
</servlet-mapping>

bdsServiceContext.xml

<!--去掉之前的FlexRemotingServiceExporter,替换成下面的Exporter-->
<!--FlexRemotingServiceProxyExporter会自动扫描标注了BdsService的BEAN,并将其注册为BDS服务-->
<bean id="flexServiceExporter"
class="steel.web.flex.FlexRemotingServiceProxyExporter">
<property name="messageBroker"
ref="mySpringManagedMessageBroker" />
</bean>


(附件中提供Eclipse/Flex项目源代码)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值