与Spring BlazeDS Integration相比,更简单的实现来调用spring bean

 

注:后面使用SBI替代Spring BlazeDS Integration

 

1.介绍:

为了使flex客户端能够直接调用服务端的spring bean,SBI提供的此种功能,SBI使用DispatchServlet代理转发MessageBrokerServlet的请求,增加了一些无用的类及相关配置,

而其实完成相同的功能,最简只需两个类即可.

 

2.扩展实现

 

BlazeDS本身提供一个AbstractBootstrapService的类用于扩展,该类主要是在BlazeDS初始化时用于动态创建 services, destinations, and adapters. rapid扩展了该类,用于将spring applicationContext的bean自动导出为destination,以供flex客户端调用. SpringRemotingDestinationBootstrapService 自动导出包含"@RemoteObject标注及以FlexService结尾"的Spring Bean为RemotingDestination


public class SpringRemotingDestinationBootstrapService extends AbstractBootstrapService {

    public static final String DEFAULT_INCLUDE_END_WITH_BEANS = "FlexService";
    
        private String destChannel;
        private String destSecurityConstraint;
        private String destScope;
        private String destAdapter;
        private String destFactory;
        
        private String serviceId;
        
        private String includeEndsWithBeans;

    public void initialize(String id, ConfigMap properties)
    {
        serviceId = properties.getPropertyAsString("service-id", "remoting-service");
        
                destFactory = properties.getPropertyAsString("dest-factory", "spring");
                destAdapter = properties.getProperty("dest-adapter");
                destScope = properties.getProperty("dest-scope");
                destSecurityConstraint = properties.getProperty("dest-security-constraint");
                destChannel = properties.getPropertyAsString("dest-channel","my-amf");
                
                includeEndsWithBeans = properties.getPropertyAsString("includeEndsWithBeans",DEFAULT_INCLUDE_END_WITH_BEANS);
                
                Service remotingService = broker.getService(serviceId);
                if(remotingService == null) {
                        throw createServiceException("not found Service with serviceId:"+serviceId);
                }
        
        createSpringDestinations(remotingService);
    }

        private ServiceException createServiceException(String message) {
                ServiceException ex = new ServiceException();
                ex.setMessage(message);
                return ex;
        }

        private void createSpringDestinations(Service remotingService) {
                WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(broker.getInitServletContext());
                List<String> addedBeanNames = new ArrayList();
                for(String beanName : wac.getBeanDefinitionNames()) {
                        Class type = wac.getType(beanName);
                        
                        boolean isCreateSpringDestination = type.isAnnotationPresent(RemotingObject.class) 
                                                                                || beanName.endsWith(includeEndsWithBeans) 
                                                                                || isCreateDestination(beanName,type);
                        
                        if(isCreateSpringDestination) {
                                createSpringDestination(remotingService, beanName);
                                addedBeanNames.add(beanName);
                        }
                }
                System.out.println("[Auto Export Spring to RemotingDestination],beanNames="+addedBeanNames);
        }

        protected boolean isCreateDestination(String beanName,Class type) {
                return false;
        }

    /*
    <!--
        动态生成的配置内容
    -->
    <destination id="sampleVerbose">
        <channels>
            <channel ref="my-secure-amf" />
        </channels>
        <adapter ref="java-object" />
        <security>
            <security-constraint ref="sample-users" />
        </security>
        <properties>
            <source>my.company.SampleService</source>
            <scope>session</scope>
            <factory>myJavaFactory</factory>
        </properties>
    </destination>     
     */
        protected void createSpringDestination(Service service, String destinationId) {
                flex.messaging.services.remoting.RemotingDestination destination = (flex.messaging.services.remoting.RemotingDestination)service.createDestination(destinationId);
        
        destination.setSource(destinationId);
        destination.setFactory(destFactory);
        
        if(destAdapter != null) 
                destination.createAdapter(destAdapter);
        if(destScope != null) 
                destination.setScope(destScope);
        if(destSecurityConstraint != null)
                destination.setSecurityConstraint(destSecurityConstraint);
        if(destChannel != null)
                destination.addChannel(destChannel);
        
        service.addDestination(destination);
        }

}
 

3.配置

将该类与网上的SpringFactory结合,即可使用. 以下为service-config.xml中关于自动导出的配置.

 

 

        <!-- 创建Spring RemotingDestination使用,与spring-remoting-service配合使用 -->
        <factories>
                <factory id="spring" class="cn.org.rapid_framework.flex.messaging.factories.SpringFactory"/>
        </factories>
        
    <services>
        <service-include file-path="remoting-config.xml" />
        <service-include file-path="proxy-config.xml" />
        <service-include file-path="messaging-config.xml" />
        
        <!-- 
                自动导出包含"@RemoteObject标注及以FlexService结尾"的Spring Bean为RemotingDestination
                FlexService结尾可以通过includeEndsWithBeans变量指定
        -->
        <service id="spring-remoting-service" class="cn.org.rapid_framework.flex.messaging.services.SpringRemotingDestinationBootstrapService">
                <!-- 其它生成的RemotingDestination默认属性 -->
                <properties>
                        <!-- 
                        <service-id></service-id>
                        <dest-factory></dest-factory>
                        <dest-adapter></dest-adapter>
                        <dest-scope></dest-scope>
                        <dest-channel></dest-channel>
                        <dest-security-constraint></dest-security-constraint>
                        <includeEndsWithBeans></includeEndsWithBeans>
                         -->
                </properties>
        </service>
                
    </services>

 

4.flex客户端调用

 

//简单示例调用
this.blogFlexService = new RemoteObject("blogFlexService");

//这里需要指定endpoint,因为是动态的RemotingDestination,而静态的RemotingDestination ,flex编译器会将endpoint编译进源代码.
//这个也是flex编译器需要指定配置文件而导致使用flex经常会犯的错误之一.
this.blogFlexService.endpoint = '../messagebroker/amf';

 

5.结论

 

 

与SBI相比,更加简单即可完成相同功能。并且通过AbstractBootstrapService,你可以很容易的完成将Java Bean, Or EJB3的session bean导出为destinations以供flex客户端直接调用.

具体使用请下载rapidframework并查看flex插件

 

rapid官方网站: http://www.rapid-framework.org.cn

 

 

你可能感兴趣的:(spring,bean,xml,Flex,Security)