您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“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進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。