Spring RMI實現

本篇博文遠程接口及其實現類代碼不再放上來,參考博文Web項目中JAVA RMI實現中的代碼

一、服務器端代碼

  1. 建立遠程接口,該接口不用再像JAVA RMI中繼承Romote類了。
  2. 建立遠程接口的實現類,該類不用再像JAVA RMI中繼承java.rmi.UnicastRemoteObject類,構造方法也不需要創建。
  3. 配置spring配置文件application.xml文件如下:
    <!--遠程接口實現類-->
    <bean id="emailService" class="com.jackmouse.rmi.email.service.EmailService"/>
    
    <bean id="serviceExporter" class="org.springframework.remoting.rmi.RmiServiceExporter">
       <!--服務名-->
       <property name="service" ref="emailService"></property>
       <!--serviceName屬性用來在RMI註冊表中註冊一個服務-->
       <property name="serviceName" value="email"></property>
       <property name="serviceInterface" value="com.jackmouse.rmi.email.service.IEmailService"/>
       <property name="registryPort" value="8888"></property>
    </bean>
    
    
  4. web.xml中配置DispatcherServlet並設置contextConfigLocation值爲application.xml
  5. 發佈項目

二、客戶端代碼

  1. 創建與服務器端相同的遠程接口
  2. 配置spring配置文件application.xml文件如下:
    <bean id="emailService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
        //
        <property name="serviceUrl" value="rmi://127.0.0.1:8888/email"/>
        <property name="serviceInterface" value="com.jackmouse.rmi.email.service.IEmailService"/>
        <!-- 預查找遠程對象 默認爲true -->
        <property name="lookupStubOnStartup" value="false"/>
        <!-- 是否刷新遠程調用緩存的stub -->
        <property name="refreshStubOnConnectFailure" value="true"></property>
    </bean>
    
  3. 測試類
    package packageofrmi;
    
    import java.net.MalformedURLException;
    import java.rmi.Naming;
    import java.rmi.NotBoundException;
    import java.rmi.RemoteException;
    
    import com.jackmouse.rmi.email.service.IEmailService;
     
    /**
     * 客戶端測試
     */
    public class TestClient {
     
    	public static void main(String[] args) {
            String title = "rmi測試";//郵件主題
            String password = "XXX";//發件人密碼
            String to = "[email protected]";//收件人郵箱賬號
            String from = "[email protected]";//發件人郵箱賬號
            String content="123";//郵件內容
    
            ApplicationContext ctx =new ClassPathXmlApplicationContext("application.xml");
        	IEmailService emailService = (IEmailService)ctx.getBean("email");
        	System.out.println(emailService.send(from,password,title,content,to));
        }
    }
    

三、注意點

當rmi服務器在遠程服務器時,如果遠程服務器有多個網卡,就需要指定某個ip。
服務器端需要像JAVA RMI中創建ServletContextListener監聽器的子類EmailServiceListener並在contextInitialized方法中寫入如下代碼

System.setProperty("java.rmi.server.hostname","49.*.*.*");

但是在spring中可以通過配置MethodInvokingFactoryBean進行靜態注入來配置某些系統配置,所以在application.xml中加入如下配置即可代替以上代碼的作用

<!--靜態注入服務器的hostname-->
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetObject" value="#{@systemProperties}" />
    <property name="targetMethod" value="putAll" />
    <property name="arguments">
        <props>
            <prop key="java.rmi.server.hostname" >遠程服務器的公網ip</prop>
        </props>
    </property>
</bean>

#{@systemProperties}等效於java.lang.System.getProperties()方法返回的Properties對象。
這個配置的通俗理解:在bean的生命週期的初始化階段,通過SpEL表達式,引用systemProperties的bean,通過MethodInvokingFactoryBean調用引用bean的putAll方法,將所配置的屬性(moaLogPath、moaPort…等),注入到System的Properties中。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章