Java 结合 Netty 和 Spring MVC
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18374277/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Combine Netty and Spring MVC
提问by lute
How can I configure Netty in Spring MVC. When and where should I start the Netty tcp server? Should I init netty once the Spring starts? Could someone show me an example such as the Spring configuration xml file or something eles? Thanks!
如何在 Spring MVC 中配置 Netty。我应该何时何地启动 Netty tcp 服务器?Spring 开始后我应该初始化 netty 吗?有人可以给我看一个例子,比如 Spring 配置 xml 文件或其他东西吗?谢谢!
回答by Jonathan
Just create a bean with start
and stop
methods that are responsible for starting up and shutting down the Netty server and then register the bean in the context with appropriate init and destroy hooks, e.g.:
只需创建一个负责启动和关闭 Netty 服务器的 beanstart
和stop
方法,然后使用适当的 init 和 destroy 钩子在上下文中注册 bean,例如:
<bean id="myNettyServer" class="x.y.z.MyNettyServer" init-method="start" destroy-method="shutdown"/>
Or alternatively use @PostConstruct
and @PreDestroy
annotations if you don't want to use XML configuration.
或者@PostConstruct
,@PreDestroy
如果您不想使用 XML 配置,也可以使用和注释。
回答by seanhodges
It really depends what you are using Netty for. Assuming you are using it as an embedded HTTP server running on a separate port, you could simply initialise it within a Spring bean. I've achieved this in the past using a useful Netty/Atmosphere wrapper called Nettosphere:
这实际上取决于您使用 Netty 的目的。假设您将它用作在单独端口上运行的嵌入式 HTTP 服务器,您可以简单地在 Spring bean 中对其进行初始化。过去,我使用名为Nettosphere的有用 Netty/Atmosphere 包装器实现了这一点:
@Service
public class NettyServer implements ServletContextAware {
private ServletContext servletContext;
private Nettosphere server;
@Autowired
private MyStatusHandler statusHandler;
@PostConstruct
public void initialiseNettyServer() {
String rootPath = servletContext.getContextPath() + "/api";
server = new Nettosphere.Builder().config(
new Config.Builder()
.host(SERVER_HOST)
.port(SERVER_PORT)
.resource(rootPath + "/status", statusHandler)
.build())
.build();
server.start();
}
@PreDestroy
public void shutdownNettyServer() {
server.stop();
}
}
This assumes the annotation-based configurationin Spring, you can easily achieve the same result using XML as explained in Jonathan'sanswer.
这假设Spring 中基于注释的配置,您可以使用 XML 轻松实现与Jonathan 的回答中解释的相同的结果。
Of course, you may prefer to use Netty directly, in which case the same principle applies, but you will need to dig into the Netty user guidea bit to bootstrap the server correctly.
当然,您可能更喜欢直接使用 Netty,在这种情况下,同样的原则适用,但您需要深入研究Netty 用户指南以正确引导服务器。
回答by Anton Shchastnyi
Option 1 (Just the code):
Here's a really good example showing how to bootstrap Netty with a handler supporting Servlets (which in turn will delegate the job to Spring MVC) https://github.com/rstoyanchev/netty-spring-mvc
选项 1(仅代码):
这是一个非常好的示例,展示了如何使用支持 Servlets 的处理程序引导 Netty(这又会将工作委托给 Spring MVC)https://github.com/rstoyanchev/netty-spring-mvc
There you define ServletNettyHandlerplus Java-based Spring MVC configurer (DispatcherServletChannelInitializer), and the TestControlleruses @Controller& @RequestMappingannotations as it always does in these cases.
在那里你定义了ServletNettyHandler加上基于 Java 的 Spring MVC 配置器(DispatcherServletChannelInitializer),并且TestController使用@Controller和@RequestMapping注释,就像在这些情况下一样。
Notes: Consider updating Netty & Spring version of the example to get it work.
注意:考虑更新示例的 Netty & Spring 版本以使其工作。
Option 2 (Just the blog post):
I've found a blog post describing the process. http://www.hypersocket.com/content/?p=12
选项 2(仅博客文章):
我找到了一篇描述该过程的博客文章。http://www.hypersocket.com/content/?p=12
回答by Nickolay Surkov
Look at the Cruzeira project that brings Netty.io to Spring Framework implementing a subset of the Servlet API https://github.com/fabiofalci/cruzeira
查看将 Netty.io 引入 Spring Framework 的 Cruzeira 项目,实现了 Servlet API 的一个子集 https://github.com/fabiofalci/cruzeira
回答by Boris Treukhov
Actually with Spring 5 you can configure a Spring 5 Webfluxapplication instead, it looks like a robust reactive alternative. The following lines (Config.start()
) run a small HTTP server in parallel with the main execution with a Spring context.
实际上,使用 Spring 5,您可以配置Spring 5 Webflux应用程序,它看起来像是一个强大的响应式替代方案。下面几行 ( Config.start()
) 与 Spring 上下文的主要执行并行运行一个小型 HTTP 服务器。
@Configuration
public class Config extends DelegatingWebFluxConfiguration{
@Bean
String test(){
return "Hello WOrLd";
}
@Bean
AdminController controller(){
return new AdminController();
}
public static void start() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class);
HttpHandler handler = WebHttpHandlerBuilder.applicationContext(applicationContext).build();
ReactorHttpHandlerAdapter adapter = new ReactorHttpHandlerAdapter(handler);
HttpServer.create("0.0.0.0", 8082).newHandler(adapter).subscribe();
}
}
controller code:
控制器代码:
@RestController
public class AdminController {
@Autowired
String text;
@GetMapping(path = "/commands")
Mono<String> commands(){
return Mono.just(text);
}
}
build.gradle
构建.gradle
compile 'org.springframework:spring-context:5.0.2.RELEASE'
compile 'org.springframework:spring-web:5.0.2.RELEASE'
compile 'org.springframework:spring-webflux:5.0.2.RELEASE'
compile 'io.projectreactor.ipc:reactor-netty:0.7.2.RELEASE'
P.S. this example only uses Spring without Spring Boot which as good as a side embedded web server, but you should consider using Spring Boot for a full-fledged microservice development.
PS 这个例子只使用 Spring 而没有 Spring Boot,它和一个侧面嵌入式 Web 服务器一样好,但是你应该考虑使用 Spring Boot 来进行成熟的微服务开发。