Spring http服务远程调用实现过程解析
最近公司有个新的需求,写了一个接口,想要把服务暴露出去,但是这个服务所在的进程是非web项目,(可以理解成schedule/batch等进程项目),所以没有tomcat等容器,而且只有这一个服务,无论是加dubbo服务还是加tomcat等容器都显得复杂了。那么应该如何将服务暴露出去?
经过网上搜索后,最终解决问题,记录在此。
为了快速搭建,使用springboot来搭建项目:
项目结构如图:
首先需要创建一个接口,服务的提供者和服务的调用方都依赖这个模块。
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();
/**
* 根据姓名获取年龄
* @param name 姓名
* @return 年龄
*/
@NotNull
Integer getAge(@Nullable String name);
}
然后在service模块中,实现接口作为服务的提供方,需要依赖的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
实现接口:
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;
}
}
暴露服务:
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服务暴露出去
*/
@Bean
public SimpleHttpInvokerServiceExporter serviceExporter() {
SimpleHttpInvokerServiceExporter exporter = new SimpleHttpInvokerServiceExporter();
exporter.setService(userService);
exporter.setServiceInterface(IUserService.class);
return exporter;
}
/**
* 为暴露的服务启用http服务
* @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;
}
}
启动服务。
然后是服务的调用方,依赖有:
<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代理工厂调用服务
* @return http代理工厂创建代理对象
*/
@Bean
public HttpInvokerProxyFactoryBean httpInvokerProxyFactoryBean() {
HttpInvokerProxyFactoryBean factoryBean = new HttpInvokerProxyFactoryBean();
factoryBean.setServiceUrl("http://localhost:9999/userService");
factoryBean.setServiceInterface(IUserService.class);
return factoryBean;
}
}
使用接口,调用方法:
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;
}
}
运行,调用test路径测试调用结果。
项目完整结构:
以上是 Spring http服务远程调用实现过程解析 的全部内容, 来源链接: utcz.com/z/311914.html