使用SpringBoot进行远程RMI调用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/singgel/article/details/82993138

SpringBoot的开发确实及其快速,但是其中也不免有一些需要注意的地方,此次使用SpringBoot进行RMI调用完全是相适应当下的Spring发展趋势。代码的git地址,拷贝吧少年:https://github.com/singgel/Spring-SkillTree

此次写的比较简单,首先从服务端的创建开始:

   1、首先建立一个服务接口类,里面的方法什么的随便定义,此处附上我的代码

package com.hks.springrmi.service;

public interface RMIExService {

    String invokingRemoteService();

}

然后定义一个实现该接口的类:

package com.hks.springrmi.service.impl;

import com.hks.springrmi.service.RMIExService;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;

/**
 * @Author: hekuangsheng
 * @Date: 2018/10/10
 */
@Service(value="rmiExServiceImpl")
public class RMIExServiceImpl implements RMIExService{


        @PostConstruct
        public void initMethod(){
            System.out.println("我是初始化方法时调用的");
        }

        @Override
        public String invokingRemoteService() {
            // TODO Auto-generated method stub
            String result="欢迎你调用远程接口";
            return result;
        }

}
 

接下来是配置bean,之前这块是配置在xml文件中的,但是SpringBoot推荐使用全注解,完全按照java自有的方式去调用,所以咱们也不能对着干,按照人家的约定来,其实也还是挺方便的

配置类代码:

package com.hks.springrmi.config;

import com.hks.springrmi.service.RMIExService;
import com.hks.springrmi.service.impl.RMIExServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.remoting.rmi.RmiServiceExporter;

/**
 * @Author: hekuangsheng
 * @Date: 2018/10/10
 */
@Configuration
public class RMIConfig {

    @Autowired
    @Qualifier("rmiExServiceImpl")
    private RMIExServiceImpl serviceImpl;

    /**
     * 方法描述:
     * 注意事项:
     *
     * @return
     * @Exception 异常对象
     */
    @Bean
    public RmiServiceExporter initRmiServiceExporter() {
        RmiServiceExporter exporter = new RmiServiceExporter();
        exporter.setServiceInterface(RMIExService.class);
        exporter.setServiceName("rmiService");
        exporter.setService(serviceImpl);
        exporter.setServicePort(6666);
        return exporter;
    }
}

调试这块的时候有坑,就是你设定了exporter.setServicePort(6666);这块代码之后,却并不起作用,RMI本身就是端口绑定不固定,此处虽然显视的定义了该接口但是却并没有起作用,通过查看服务端启动日志,我可以看到如下的一段话:

2018-10-10 10:24:56.707  INFO 10918 --- [           main] o.s.remoting.rmi.RmiServiceExporter      : Looking for RMI registry at port '1099'
2018-10-10 10:24:56.714  INFO 10918 --- [           main] o.s.remoting.rmi.RmiServiceExporter      : Could not detect RMI registry - creating new one
2018-10-10 10:24:56.743  INFO 10918 --- [           main] o.s.remoting.rmi.RmiServiceExporter      : Binding service 'rmiService' to RMI registry: RegistryImpl[UnicastServerRef [liveRef: [endpoint:[127.0.0.1:1099](local),objID:[0:0:0, 0]]]]
2018-10-10 10:24:56.974  INFO 10918 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup

这里说明这个远程服务被绑定到了127.0.0.1:1099这个地址上。此处主要是针对客户端报地址找不到的错误。到这里基本上配置算是完成了,但是有一点需要注意,就是在你的Bootstrap类中需要声明下扫描注解类的注解@ComponentScan。我遇到了我的服务实现类没有自动加载到容器中的错误,所以此处需要注意下。 

下面就是我们的客户端了,客户端的配置很简单,大环境还是Springboot下。

你首先还是需要将服务端的接口类打成jar包放入你的客户端。

        <dependency>
			<groupId>com.hks</groupId>
			<artifactId>spring-rmi</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>

然后配置一个RMI的配置类,此处需要注入Bean,RmiProxyFactoryBean这个类是Spring提供的管理RMI远程服务的工厂类,避免了原使使用Naming.lookup(),违反Spring依赖注入原则的形式。下面是配置的客户端类: 

package com.hks.springrmiclient.config;

import com.hks.springrmi.service.RMIExService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.remoting.rmi.RmiProxyFactoryBean;

/**
 * @Author: hekuangsheng
 * @Date: 2018/10/10
 */
@Configuration
public class RMIClientConfig {

    @Bean(name = "rmiService")
    public RmiProxyFactoryBean initRmiProxyFactoryBean() {
        RmiProxyFactoryBean factoryBean = new RmiProxyFactoryBean();
        factoryBean.setServiceUrl("rmi://127.0.0.1:1099/rmiService");
        factoryBean.setServiceInterface(RMIExService.class);
        return factoryBean;
    }

}

调用方式是:

package com.hks.springrmiclient;

import com.hks.springrmi.service.RMIExService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.remoting.rmi.RmiProxyFactoryBean;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringRmiClientApplicationTests {

	@Autowired
	@Qualifier("rmiService")
	private RmiProxyFactoryBean factoryBean;


	@Test
	public void contextLoads() {
		RMIExService service=(RMIExService)factoryBean.getObject();
		System.out.println(service.invokingRemoteService());

	}

}

之前在类中已经注入了属性,到这里完整的例子已经完成了,很简单,对于传输对象来说,需要对对象进行序列化。

 

猜你喜欢

转载自blog.csdn.net/singgel/article/details/82993138