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

首先需要創(chuàng)建一個接口,服務(wù)的提供者和服務(wù)的調(diào)用方都依賴這個模塊。
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模塊中,實現(xiàn)接口作為服務(wù)的提供方,需要依賴的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
實現(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工廠類
*/
@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;
}
}
啟動服務(wù)。
然后是服務(wù)的調(diào)用方,依賴有:
<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)建代理對象
*/
@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;
}
}
運行,調(diào)用test路徑測試調(diào)用結(jié)果。
項目完整結(jié)構(gòu):

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
python+OpenCV人臉識別考勤系統(tǒng)實現(xiàn)的詳細(xì)代碼
作為一個基于人臉識別算法的考勤系統(tǒng)的設(shè)計與實現(xiàn)教程,以下內(nèi)容將提供詳細(xì)的步驟和代碼示例。本教程將使用 Python 語言和 OpenCV 庫進行實現(xiàn),需要的朋友可以參考下2023-05-05
淺談配置OpenCV3 + Python3的簡易方法(macOS)
下面小編就為大家分享一篇淺談配置OpenCV3 + Python3的簡易方法(macOS),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-04-04

