rmi of spring

本文介绍了如何使用Spring框架实现RMI和HTTP Invoker两种远程服务调用方式。包括服务器端和服务接口的配置,以及客户端如何通过Spring配置访问远程服务。
基于Spring实现远程服务编程:
[urlhttp://www.51cto.com/art/200611/34262.htm][/url]


[size=medium]用Spring动态调用RMI远程对象 [/size]

// 不需要通过BeanFactory直接动态调用远程对象

DistributeCenterBO distributeCenterBO = null;
RmiProxyFactoryBean rmiProxyFactoryBean = new RmiProxyFactoryBean();
rmiProxyFactoryBean.setServiceInterface(DistributeCenterBO.class);
rmiProxyFactoryBean.setServiceUrl(
"rmi://localhost:1199/DistributeCenterBO");
try {
rmiProxyFactoryBean.afterPropertiesSet(); //更改ServiceInterface或ServiceUrl之后必须调用该方法,来获取远程调用桩
} catch (Exception ex) {
}

if (rmiProxyFactoryBean.getObject() instanceof DistributeCenterBO) {
distributeCenterBO = (DistributeCenterBO)
rmiProxyFactoryBean.getObject();
distributeCenterBO.register(SubscriberImpl.subscriberId);
}


[size=medium]rmi和httpInvoker [/size]

对于富客户端来说,和服务器端的通讯有很多种方式,不过我一般用的就是rmi或者httpInvoker。
spring为多种远程调用都提供了包装:
一。对于RMI来说
1、服务器端: <bean class="org.springframework.remoting.rmi.RmiServiceExporter">
<property name="serviceName"><value>ExampleService</value></property>
<property name="service"><ref bean="exampleManager"/></property>
<property name="serviceInterface"><value>com.example.server.service.manager.base.IExampleManager</value></property>
<property name="registryPort"><value>777</value></property>
</bean>


Spring中合理的配置RMI:

因为RMI stub被连接到特定的端点,不仅仅是为每个调用打开一个给定的目标地址的连接,所以如果重新启动RMI端点主机的服务器,那么就需要重新注册这些stub,并且客户端需要再次查询它们。
虽然目标服务的重新注册在重新启动时通常会自动发生,不过此时客户端保持的stub将会变的陈旧,且客户端不会注意这些,除非他们再次尝试调用stub上的方法,而这也将throw一个连接失败的异常。
为了避免这种情形,Spring的RmiProxyFactoryBean提供了一个refreshStubOnConnectFailure的bean属性,如果调用失败,并且连接异常的话,将它设定为true来强制重新自动查询stub。
<bean id="reportService"
class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<property name="serviceUrl">
<value>${showcasewiz.report.serviceurl}</value>
</property>
<property name="serviceInterface">
<value>com.meetexpo.showcase.backend.service.ReportService</value>
</property>
[color=blue] <property name="refreshStubOnConnectFailure">
<value>true</value>
</property>[/color]
</bean>
stub查询的另一个问题是,目标RMI服务器和RMI注册项在查询时要为可用的。如果客户端在服务器启动之前,尝试查询和缓存该服务stub,那么客户端的启动将会失败(即使还不需要该服务)。
为了能够惰性查询服务stub,设定RmiProxyFactoryBean的lookupStubOnStarup标志为false。然后在第一次访问时查询该stub,也就是说,当代理上的第一个方法被调用的时候去主动查询stub,同时被缓存。这也有一个缺点,就是直到第一次调用,否则无法确认目标服务是否实际存在。
<bean id="reportService"
class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<property name="serviceUrl">
<value>${showcasewiz.report.serviceurl}</value>
</property>
<property name="serviceInterface">
<value>com.meetexpo.showcase.backend.service.ReportService</value>
</property>
[color=blue] <property name="lookupStubOnStartup">
<value>false</value>
</property>
<property name="refreshStubOnConnectFailure">
<value>true</value>
</property>[/color]
</bean>

还有一个属性就是cacheStub,当它设置为false的时候,就完全避免了stub的缓存,但影响了性能。需要的时候还是可以试试。


这段spring的配置文件就定义了服务器端的一个bean,可以暴露给客户端通过RMI方式来访问了。
examleMaanger这个bean在实现时,完全不需要知道它自己有一天还会被通过rmi方式被远程访问。
2、客户端:
<bean id="cityService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<property name="serviceUrl"><value>rmi://localhost:777/CityService</value></property>
<property name="serviceInterface"><value>com.example.server.service.manager.base.IExampleManager</value></property>
<property name="lookupStubOnStartup"><value>true</value></property>
<property name="cacheStub"><value>true</value></property>
</bean>这段spring的配置文件定义了客户端的一个bean,这样就可在客户端使用exampleManager了,就如同在本地使用一样,完全没有什么不同。


二。对于httpInvoker来说,其配置比rmi方式要麻烦一些,而且据说其效率也要比rmi方式差,不过这一点我到没有亲身证实过,只是听说而已。但是httpInvoker有一个优点却足以抵消其所有的缺点,那就是它是通过web的端口来访问的。这样,只要能够浏览页面,就能够进行远程调用,避免了rmi方式有时无法通过防火墙的问题。
1、服务器端:
httpInvoker需要web容器的支持,因此需要将服务器端程序部署到web容器内。
在web.xml文件中
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<servlet>
<servlet-name>remote</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>remote</servlet-name>
<url-pattern>/remote/*</url-pattern>
</servlet-mapping>
注意第一行定义的listener一定要有,否则下面提到的remote-servlet.xml中要引用的bean就会无法找到。
我们定义了一个servlet,名字叫remote,因此在WEB-INF目录下我们建一个名字为remote-servlet.xml的文件,内容为
<?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="/exampleService" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
<property name="service"><ref bean="exampleManager"/></property>
<property name="serviceInterface">
<value>com.example.server.service.manager.IExampleManager</value>
</property>
</bean>
</beans>这样服务器端的配置就完成了。exampleManager这个bean被暴露给了客户端
2、客户端:
<bean id="exampleService" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
<property name="serviceUrl">
<value>http://localhost:80/remote/exampleService</value>
</property>
<property name="serviceInterface">
<value>com.example.server.service.manager.IExampleManager</value>
</property>
</bean> OK,这样客户端的配置就完成了。
【完美复现】面向配电网韧性提升的移动储能预布局与动态调度策略【IEEE33节点】(Matlab代码实现)内容概要:本文介绍了基于IEEE33节点的配电网韧性提升方法,重点研究了移动储能系统的预布局与动态调度策略。通过Matlab代码实现,提出了一种结合预配置和动态调度的两阶段优化模型,旨在应对电网故障或极端事件时快速恢复供电能力。文中采用了多种智能优化算法(如PSO、MPSO、TACPSO、SOA、GA等)进行对比分析,验证所提策略的有效性和优越性。研究不仅关注移动储能单元的初始部署位置,还深入探讨其在故障发生后的动态路径规划与电力支援过程,从而全面提升配电网的韧性水平。; 适合人群:具备电力系统基础知识和Matlab编程能力的研究生、科研人员及从事智能电网、能源系统优化等相关领域的工程技术人员。; 使用场景及目标:①用于科研复现,特别是IEEE顶刊或SCI一区论文中关于配电网韧性、应急电源调度的研究;②支撑电力系统在灾害或故障条件下的恢复力优化设计,提升实际电网应对突发事件的能力;③为移动储能系统在智能配电网中的应用提供理论依据和技术支持。; 阅读建议:建议读者结合提供的Matlab代码逐模块分析,重点关注目标函数建模、约束条件设置以及智能算法的实现细节。同时推荐参考文中提及的MPS预配置与动态调度上下两部分,系统掌握完整的技术路线,并可通过替换不同算法或测试系统进一步拓展研究。
先看效果: https://pan.quark.cn/s/3756295eddc9 在C#软件开发过程中,DateTimePicker组件被视为一种常见且关键的构成部分,它为用户提供了图形化的途径来选取日期与时间。 此类控件多应用于需要用户输入日期或时间数据的场景,例如日程管理、订单管理或时间记录等情境。 针对这一主题,我们将细致研究DateTimePicker的操作方法、具备的功能以及相关的C#编程理念。 DateTimePicker控件是由.NET Framework所支持的一种界面组件,适用于在Windows Forms应用程序中部署。 在构建阶段,程序员能够通过调整属性来设定其视觉形态及运作模式,诸如设定日期的显示格式、是否展现时间选项、预设的初始值等。 在执行阶段,用户能够通过点击日历图标的下拉列表来选定日期,或是在文本区域直接键入日期信息,随后按下Tab键或回车键以确认所选定的内容。 在C#语言中,DateTime结构是处理日期与时间数据的核心,而DateTimePicker控件的值则表现为DateTime类型的实例。 用户能够借助`Value`属性来读取或设定用户所选择的日期与时间。 例如,以下代码片段展示了如何为DateTimePicker设定初始的日期值:```csharpDateTimePicker dateTimePicker = new DateTimePicker();dateTimePicker.Value = DateTime.Now;```再者,DateTimePicker控件还内置了事件响应机制,比如`ValueChanged`事件,当用户修改日期或时间时会自动激活。 开发者可以注册该事件以执行特定的功能,例如进行输入验证或更新关联的数据:``...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值