Spring http服務(wù)遠(yuǎn)程調(diào)用實(shí)現(xiàn)過(guò)程解析
最近公司有個(gè)新的需求,寫(xiě)了一個(gè)接口,想要把服務(wù)暴露出去,但是這個(gè)服務(wù)所在的進(jìn)程是非web項(xiàng)目,(可以理解成schedule/batch等進(jìn)程項(xiàng)目),所以沒(méi)有tomcat等容器,而且只有這一個(gè)服務(wù),無(wú)論是加dubbo服務(wù)還是加tomcat等容器都顯得復(fù)雜了。那么應(yīng)該如何將服務(wù)暴露出去?
經(jīng)過(guò)網(wǎng)上搜索后,最終解決問(wèn)題,記錄在此。
為了快速搭建,使用springboot來(lái)搭建項(xiàng)目:
項(xiàng)目結(jié)構(gòu)如圖:

首先需要?jiǎng)?chuàng)建一個(gè)接口,服務(wù)的提供者和服務(wù)的調(diào)用方都依賴(lài)這個(gè)模塊。
package com.xiazhi.spring.service.api;
import com.sun.istack.internal.NotNull;
import com.sun.istack.internal.Nullable;
/**
* @author 趙帥
* @date 2020/6/8
*/
public interface IUserService {
/**
* 獲取姓名
* @return 姓名
*/
String getName();
/**
* 根據(jù)姓名獲取年齡
* @param name 姓名
* @return 年齡
*/
@NotNull
Integer getAge(@Nullable String name);
}
然后在service模塊中,實(shí)現(xiàn)接口作為服務(wù)的提供方,需要依賴(lài)的jar包有:
<dependencies>
<dependency>
<groupId>com.xiazhi</groupId>
<artifactId>spring-service-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
</dependencies>
配置文件需要加上:
spring.main.web-application-type=none
實(shí)現(xiàn)接口:
package com.xiazhi.spring.service.impl;
import com.sun.istack.internal.NotNull;
import com.sun.istack.internal.Nullable;
import com.xiazhi.spring.service.api.IUserService;
import org.springframework.stereotype.Service;
/**
* @author 趙帥
* @date 2020/6/8
*/
@Service
public class UserServiceImpl implements IUserService {
@Override
public String getName() {
return "張一";
}
@Override
@NotNull
public Integer getAge(@Nullable String name) {
if ("".equals(name)) {
return 10;
}
return 18;
}
}
暴露服務(wù):
package com.xiazhi.spring.service.config;
import com.sun.net.httpserver.HttpHandler;
import com.xiazhi.spring.service.api.IUserService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.remoting.httpinvoker.SimpleHttpInvokerServiceExporter;
import org.springframework.remoting.support.SimpleHttpServerFactoryBean;
import java.util.HashMap;
import java.util.Map;
/**
* @author 趙帥
* @date 2020/6/8
*/
@Configuration
public class HttpInvokerConfiguration {
private final IUserService userService;
private final TaskExecutor taskExecutor;
public HttpInvokerConfiguration(IUserService userService, TaskExecutor taskExecutor) {
this.userService = userService;
this.taskExecutor = taskExecutor;
}
/**
* 將IUserService服務(wù)暴露出去
*/
@Bean
public SimpleHttpInvokerServiceExporter serviceExporter() {
SimpleHttpInvokerServiceExporter exporter = new SimpleHttpInvokerServiceExporter();
exporter.setService(userService);
exporter.setServiceInterface(IUserService.class);
return exporter;
}
/**
* 為暴露的服務(wù)啟用http服務(wù)
* @return httpServer工廠類(lèi)
*/
@Bean
public SimpleHttpServerFactoryBean serverFactoryBean() {
SimpleHttpServerFactoryBean factoryBean = new SimpleHttpServerFactoryBean();
Map<String, HttpHandler> map = new HashMap<>(2);
factoryBean.setContexts(map);
factoryBean.setPort(9999);
factoryBean.setExecutor(taskExecutor);
return factoryBean;
}
}
啟動(dòng)服務(wù)。
然后是服務(wù)的調(diào)用方,依賴(lài)有:
<dependencies>
<dependency>
<groupId>com.xiazhi</groupId>
<artifactId>spring-service-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
配置文件:
package com.xiazhi.spring.config;
import com.xiazhi.spring.service.api.IUserService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean;
/**
* @author 趙帥
* @date 2020/6/8
*/
@Configuration
public class HttpServiceConfiguration {
/**
* 使用http代理工廠調(diào)用服務(wù)
* @return http代理工廠創(chuàng)建代理對(duì)象
*/
@Bean
public HttpInvokerProxyFactoryBean httpInvokerProxyFactoryBean() {
HttpInvokerProxyFactoryBean factoryBean = new HttpInvokerProxyFactoryBean();
factoryBean.setServiceUrl("http://localhost:9999/userService");
factoryBean.setServiceInterface(IUserService.class);
return factoryBean;
}
}
使用接口,調(diào)用方法:
package com.xiazhi.spring.controller;
import com.xiazhi.spring.service.api.IUserService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author 趙帥
* @date 2020/6/8
*/
@RestController
public class UserController {
private final IUserService userService;
public UserController(IUserService userService) {
this.userService = userService;
}
@GetMapping("/test")
public String test() {
String name = userService.getName();
Integer age = userService.getAge(null);
System.out.println(String.format("姓名:[%s],age:[%s]", name, age));
return name;
}
}
運(yùn)行,調(diào)用test路徑測(cè)試調(diào)用結(jié)果。
項(xiàng)目完整結(jié)構(gòu):

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
python 同時(shí)運(yùn)行多個(gè)程序的實(shí)例
今天小編就為大家分享一篇python 同時(shí)運(yùn)行多個(gè)程序的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-01-01
python3制作捧腹網(wǎng)段子頁(yè)爬蟲(chóng)
網(wǎng)上的Python教程大都是2.X版本的,python2.X和python3.X相比較改動(dòng)比較大,好多庫(kù)的用法不太一樣,我安裝的是python3.X,我們來(lái)看看詳細(xì)的例子2017-02-02
ubuntu16.04升級(jí)Python3.5到Python3.7的方法步驟
這篇文章主要介紹了ubuntu16.04升級(jí)Python3.5到Python3.7的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
Python中的random函數(shù)實(shí)例詳解
random模塊提供生成偽隨機(jī)數(shù)的函數(shù),在使用時(shí)需要導(dǎo)入random模塊,這篇文章主要介紹了Python中的random函數(shù),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-02-02
Python中常見(jiàn)的三種字符串格式化輸出方法小結(jié)
字符串格式化是編程中一個(gè)常見(jiàn)的需求,它可以們將不同類(lèi)型的數(shù)據(jù)插入到字符串中,在?Python?中,有多種方法可以執(zhí)行字符串格式化,本文為大家介紹了常見(jiàn)的三種方法,希望對(duì)大家有所幫助2024-02-02

