发表于: 2018-02-09 14:34:51
1 577
今天完成的事情
1.关于昨天的小疑问那块儿,今天试了试不加构造方法(跑出异常)会怎么样
不加的话,编译器直接报错,alt+enter之后可以选择加上无参构造方法且抛出异常。所以说这里是一定要加的。
2.感觉自己昨天对rmi的认知理解有错误,于是今天好好搜了一下是怎么回事:
RMI体系结构分以下几层:
存根和骨架层(StubandSkeletonlayer):这一层对程序员是透明的,它主要负责拦截客户端发出的方法调用请求,然后把请求重定向给远程的RMI服务。
远程引用层(RemoteReferenceLayer):RMI体系结构的第二层用来解析客户端对服务端远程对象的引用。这一层解析并管理客户端对服务端远程对象的引用。连接是点到点的。
传输层(Transportlayer):这一层负责连接参与服务的两个JVM。这一层是建立在网络上机器间的TCP/IP连接之上的。它提供了基本的连接服务,还有一些防火墙穿透策略。
进而继续搜了一下如何实现rmi,发现也非常简单,但是照着实现却实现不了:
就是上面这些步骤。
于是开始试着用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
评论