发表于: 2018-02-09 14:34:51

1 576


今天完成的事情

 1.关于昨天的小疑问那块儿,今天试了试不加构造方法(跑出异常)会怎么样

  不加的话,编译器直接报错,alt+enter之后可以选择加上无参构造方法且抛出异常。所以说这里是一定要加的。

 2.感觉自己昨天对rmi的认知理解有错误,于是今天好好搜了一下是怎么回事:

RMI体系结构分以下几层:
存根和骨架层(StubandSkeletonlayer):这一层对程序员是透明的,它主要负责拦截客户端发出的方法调用请求,然后把请求重定向给远程的RMI服务。
远程引用层(RemoteReferenceLayer):RMI体系结构的第二层用来解析客户端对服务端远程对象的引用。这一层解析并管理客户端对服务端远程对象的引用。连接是点到点的。
传输层(Transportlayer):这一层负责连接参与服务的两个JVM。这一层是建立在网络上机器间的TCP/IP连接之上的。它提供了基本的连接服务,还有一些防火墙穿透策略。

 进而继续搜了一下如何实现rmi,发现也非常简单,但是照着实现却实现不了:

(1)创建远程接口,继承java.rmi.Remote接口;
(2)创建远程类,实现远程接口;
(3)创建服务器程序,在rmiregistry注册表中注册远程对象;
(4)创建客户端程序,负责定位远程对象,并且调用远程方法。

就是上面这些步骤。

 于是开始试着用spring来搞一搞这个东西:

 先传一下项目结构:

上面的是我定义的客户端,下面的是我定义的服务端

 然后鼓舞端里面是这样:

接下来把三个文件传一下:

接口:

public interface ServerRmiI {

public String sayHi(String name);
}

接口实现:

public class ServerRmiImpl implements ServerRmiI{

public String sayHi(String name) {
return "Hi,"+name;
   
}

test:

public class Testrun {

public static void main(String[] args) {
       ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-mybatis.xml");
       context.getBean("serverTest");
       System.out.println("独享绑定成成功");
   }
}

 还有spring的配置文件:

<bean name="rmiserver" class="com.student.RMI.ServerRmiImpl"/>
<bean name="serverTest" class="org.springframework.remoting.rmi.RmiServiceExporter">
   <property name="service" ref="rmiserver"/>
   <property name="serviceName" value="serverRmiTest"/>
   <property name="serviceInterface" value="com.student.RMI.ServerRmiI"/>
   <property name="registryPort" value="1021"/>
</bean>

这样配置好之后直接跑一下,会提示对象绑定成功

 然后是客户端的:

一共就这些东西,下面分别上传一下:

接口:

public interface ServerRmiI 
public String sayHi(String name);
}

test:

public class TestRun 
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring.xml");
       ServerRmiI rmiI = (ServerRmiI) context.getBean("clentrmi");
       System.out.println(rmiI.sayHi("rmi"));
   }
}

spring配置:

<bean name="clentrmi" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
   <property name="serviceUrl" value="rmi://127.0.0.1:1021/serverRmiTest"/>
   <property name="serviceInterface" value="com.student1.service.ServerRmiI"/>
</bean>

这样,在运行之后会通过spring拿到绑定好的对象:

  这个跟我昨天的理解就不一样。可以明显的看出来是远程调用。我昨天那个还得自己打印哈希值来验证,因为引入了接口和接口的实现类,感觉怪怪的。

  3.既然理解了这些,接下来就是在项目中真正地使用这个东西了。

 我是这么类比着来的,期间也碰到了不少的坑:

  项目结构的话呢,上面已经又一个例子了,我就直接说了。我的理解就是把接口实现类的一个对象暴露出去,远程哪里有一个接口,来直接调用我们暴露的这个接口实现类的对象。

  大概就是这样,接下来说说小坑们:

 (1)我的bean都是通过自动扫描装配的,这时候应该把想要暴露的bean取消自动扫描装配:

 然后在下面写出一个这样的bean来:

<bean name="rmiserver" class="com.student.service.impl.StudentServiceImpl"/>
<bean name="serverTest" class="org.springframework.remoting.rmi.RmiServiceExporter">
   <property name="service" ref="rmiserver"/>
   <property name="serviceName" value="serverRmiTest"/>
   <property name="serviceInterface" value="com.student.service.StudentService"/>
   <property name="registryPort" value="1021"/>
</bean>

  注意,这里有个坑的,因为一直是自动扫描装配了对不对,controller里面肯定也是啊,要去controller里面取消用到的这个bean:

原来是自动注入的啦,但是现在bean咱注释掉了啊,所以这里也要对应地取消。

就这样,服务端就整好了,还是挺简单的额。。然后就是客户端了:

首先得有个对应的接口啊,于是将服务端的接口copy一份过来,然后就是spring的配置了:

 修改对应的地方就ok了,这里不细说

 最后就是写一个方法来测试了:

 直接从暴露出来的实现类里面拿出一个service对象,再调用实现类的方法就行了。

 但是这时候还会出现报错,为什么呢?因为模型类(pojo)没有序列化啦,街上对应的语句:

再次运行:ojbk:下面是我调用的方法:

System.out.println(ss.getStudent(1));

运行结果:

ojbk有没有?

 接下来是部署两台service,在web中访问随机的service:这个其实也比较好弄,借鉴了明达大佬的日报:

首先是两个service需要两个spring配置文件:

两个配置文件=是一模一样的

然后是在controller里面这样写:

public StudentService getStudentService() {
StudentService studentService;
   Integer i = (int)(Math.random()*10);
   if (i<=5){
try {
System.out.println("这是1");
           ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring.xml");
           studentService = (StudentService) context.getBean("clentrmi");
           System.out.println(studentService);
       }catch(Exception e){
System.out.println("1挂了,现在是2");
           ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring2.xml");
           studentService = (StudentService) context.getBean("clentrmi");
           System.out.println(studentService);
       }
}else {
try {
System.out.println("这是2");
           ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring2.xml");
           studentService = (StudentService) context.getBean("clentrmi");
           System.out.println(studentService);
       }catch (Exception e){
System.out.println("2挂了,现在是1");
           ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring.xml");
           studentService = (StudentService) context.getBean("clentrmi");
           System.out.println(studentService);
       }
}
return studentService;
}

用实例的地方这样写:

StudentService studentService = this.getStudentService();

如此,就可以实现随机调用了:

ojbk。

今天遇到的问题

  都在路上解决了
 今天的收获

  以上

 明天计划的事情

  完成任务8



返回列表 返回列表
评论

    分享到