本文小编为大家详细介绍“Spring原生Rpc的正确打开方式有哪些”,内容详细,步骤清晰,细节处理妥当,希望这篇“Spring原生Rpc的正确打开方式有哪些”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。
Rpc(Remote Procedure Call): 封装了内部实现的远程调用过程就是rpc,rpc主要为了简化远程服务调用,通俗的讲就是调用远程服务(跨主机,跨进程)就像调用本地方法一样。Spring Cloud体系中的Fegin 技术也可以认为是采用http协议传输数据的一种Rpc技术。
Spring中内置了六种不同数据传输方式的原生的Rpc实现,分别是WebService、Jms、Rmi、Http、Hessian(http)、Amqp。熟悉Rpc的知道,在Java中,主要是通过生成服务接口的代理来实现Rpc服务的调用,Dubbo、Motan这样,Spring的实现也是这样。在Rpc服务调用中,有两个角色,分别是服务的提供者和调用者(消费者)。一方面服务调用者通过代理,在服务调用时会传输服务定义的接口名+方法参数给到提供者。另一方面服务提供者拿到接口信息找到本地服务生成调用结果返回给调用者。所以下面所述六种Rpc实现都会有一个公共的服务接口定义,以及各自的代理实现配置。
/** * @WebService 注解只用于ws 提供的RPC服务 */ @WebService public interface AccountService { Account getAccount(String name); class Account implements Serializable { private String name; public String getName(){ return name; } public void setName(String name) { this.name = name; } } }
公共的api,在Rpc的提供者和消费者中都会使用到,提供者中会实现这个接口提供服务,消费者会通过代理,生成这个接口的代理实现 ,然后通过底层封装发送具体的消息。和使用dubbo和motan类似
@SpringBootApplication public class WsConsumerApplication { @Autowired private AccountService accountService; @PostConstruct public void callRpcService(){ System.out.println("RPC远程访问开始!"); System.err.println(accountService.getAccount("kl").getName()); System.out.println("RPC远程访问结束!"); } public static void main(String[] args) { SpringApplication.run(WsConsumerApplication.class, args); } }
每个Rpc实现都一样,都是通过注入AccountService 接口的代理实现来调用服务。不过每个Rpc的代理的配置方式会略有不同,主要体现在不同的传输技术会用到不同的配置。总的来说,连接url(http://127.0.0.1、tcp://172.0.0.1、rmi://127.0.0.1),端口、代理接口信息等都是共同需要的。
@WebService(serviceName="AccountService",endpointInterface = "com.spring.rpc.api.AccountService") @Service public class AccountServiceImpl extends SpringBeanAutowiringSupport implements AccountService { Logger logger = LoggerFactory.getLogger(getClass()); @Override @WebMethod public Account getAccount(String name) { logger.info("{} 请求获取账号!", name); Account account = new Account(); account.setName(name + "的账号"); return account; } }
和其他服务实现不一样,WebService定义服务时,需要使用@WebService和@WebMethod注解标记
@Configuration public class WsConfig { private String ipList = "127.0.0.1"; private String userName = "admin"; private String passWord = "sasa"; @Bean public SimpleHttpServerJaxWsServiceExporter rmiServiceExporter(Authenticator authenticator) { SimpleHttpServerJaxWsServiceExporter exporter = new SimpleHttpServerJaxWsServiceExporter(); exporter.setHostname("127.0.0.1"); exporter.setPort(8083); exporter.setAuthenticator(authenticator); return exporter; } @Bean public Authenticator authenticator(){ Authenticator authenticator = new Authenticator(); authenticator.setIpList(ipList); authenticator.setUserName(userName); authenticator.setPassWord(passWord); return authenticator; } }
完成如上代码,其实我们已经构建了一个完整的WebService服务,而且还加上了用户、密码和ip白名单等接口权限认证,访问:http://127.0.0.1:8083/AccountServiceImpl?WSDL 就可以看到服务的定义,如下:
@Configuration public class WsConfig { @Bean("accountService") public JaxWsPortProxyFactoryBean accountService()throws Exception{ JaxWsPortProxyFactoryBean factoryBean = new JaxWsPortProxyFactoryBean(); factoryBean.setServiceName("AccountService"); factoryBean.setPortName("AccountServiceImplPort"); factoryBean.setNamespaceUri("http://provider.ws.rpc.spring.com/"); URL wsdlDocumentUrl = new URL("http://127.0.0.1:8083/AccountServiceImpl?WSDL"); factoryBean.setWsdlDocumentUrl(wsdlDocumentUrl); factoryBean.setServiceInterface(AccountService.class); factoryBean.setUsername("admin"); factoryBean.setPassword("sasa"); return factoryBean; } }
通过声明JaxWsPortProxyFactoryBean来获得AccountService.class的代理实例。当注入服务调用方法时,实际上是触发了一次WebService的远程调用
@Service public class AccountServiceImpl implements AccountService { Logger logger = LoggerFactory.getLogger(getClass()); @Override public Account getAccount(String name) { logger.info("{} 请求获取账号!", name); Account account = new Account(); account.setName(name + "的账号"); return account; } }
@Configuration public class HttpConfig { @Bean("/AccountService") public HttpInvokerServiceExporter rmiServiceExporter(AccountServiceImpl accountService){ HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter(); exporter.setService(accountService); exporter.setServiceInterface(AccountService.class); return exporter; } @Bean public ServletRegistrationBean servletRegistrationBean(DispatcherServlet dispatcherServlet) { ServletRegistrationBean servlet = new ServletRegistrationBean(); servlet.setServlet(dispatcherServlet); servlet.setName("remoting"); servlet.setLoadOnStartup(1); servlet.addUrlMappings("/remoting/*"); return servlet; } }
@Configuration public class HttpConfig { @Bean("accountService") public HttpInvokerProxyFactoryBean accountService(){ HttpInvokerProxyFactoryBean factoryBean = new HttpInvokerProxyFactoryBean(); factoryBean.setHttpInvokerRequestExecutor(new HttpComponentsHttpInvokerRequestExecutor()); factoryBean.setServiceUrl("http://127.0.0.1:8081/remoting/AccountService"); factoryBean.setServiceInterface(AccountService.class); return factoryBean; } }
可以看到,在配置Http实现的Rpc服务消费者时,和WebService是类似的,定义一个FactoryBean就ok了。其实其他的四种Rpc实现也都大同小异。后面就不一一列举了
读到这里,这篇“Spring原生Rpc的正确打开方式有哪些”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。