SpringBoot如何详细整合Netty开发步骤解析?

2026-05-29 15:584阅读0评论SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1857个文字,预计阅读时间需要8分钟。

SpringBoot如何详细整合Netty开发步骤解析?

本文主要介绍了Spring Boot与Netty整合过程,详细解析了通过示例代码介绍的内容。对有一定学习或工作经验的读者来说,具有一定的参考价值。需要的朋友可以参考下文。

前言:上篇讲解了Netty的一个入门。

一、Spring Boot与Netty整合

1. 引言

随着微服务架构的普及,高性能、高并发的网络编程需求日益增长。Netty作为一款高性能的NIO框架,在处理高并发、低延迟的场景中有着出色的表现。而Spring Boot则是一个便捷的Java开发框架,可以将Netty整合到Spring Boot项目中,实现更高效的网络编程。

2. 整合步骤

(1)添加依赖

在Spring Boot项目中,首先需要在pom.xml文件中添加Netty和Spring Boot的依赖。

xml io.netty netty-all 4.1.42.Final org.springframework.boot spring-boot-starter

(2)创建NettyServer

在Spring Boot项目中创建一个NettyServer类,继承自SpringBootServletInitializer,实现ServletContainerInitializer接口。

javapublic class NettyServer extends SpringBootServletInitializer implements ServletContainerInitializer { @Override public void onStartup(ServletContext servletContext) throws ServletException { // 创建Netty服务器 EventLoopGroup bossGroup=new NioEventLoopGroup(); EventLoopGroup workerGroup=new NioEventLoopGroup(); try { ServerBootstrap b=new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer() { @Override protected void initChannel(SocketChannel ch) throws Exception { // 添加处理器 ch.pipeline().addLast(new NettyServerHandler()); } }) .option(ChannelOption.SO_BACKLOG, 128) .childOption(ChannelOption.SO_KEEPALIVE, true);

// 绑定端口并启动服务器 ChannelFuture f=b.bind(8080).sync(); // 等待服务器socket关闭 f.channel().closeFuture().sync(); } finally { workerGroup.shutdownGracefully(); bossGroup.shutdownGracefully(); } }}

(3)创建NettyServerHandler

在NettyServer类中创建NettyServerHandler类,继承自ChannelInboundHandlerAdapter,实现业务逻辑处理。

javapublic class NettyServerHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { // 业务处理 System.out.println(Received message: + msg); // 回复客户端 ctx.writeAndFlush(Received your message.); }}

(4)启动Spring Boot项目

SpringBoot如何详细整合Netty开发步骤解析?

通过以上步骤,Netty与Spring Boot项目成功整合。在启动Spring Boot项目后,Netty服务器将在8080端口监听。

3. 总结

本文详细介绍了Spring Boot与Netty的整合过程,通过示例代码展示了如何实现Netty服务器。对于有网络编程需求的读者,可以参考本文进行实践。

这篇文章主要介绍了springboot整合netty过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

前言

上一篇讲了netty的一个入门的demo;项目上我也把数据处理做好了,就要开始存数据库了;我用的mybatis框架,如果单独使用还是觉得比较麻烦,所以就用了springboot+mybatis+netty;本篇主要讲netty与springboot的整合,以及我在这个过程中遇到的问题,又是怎么去解决的;

正文

我在做springboot与netty整合的时候在谷歌,百度找了无数文章,都没有一篇是自己想要的,也达不到自己所想的目的;

代码

1. 新建一个springboot项目,在pom文件中添加netty依赖:

<dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>5.0.0.Alpha1</version> </dependency>

2.新建netty服务
其实可以复制上一篇文章的netty的三个服务类,做一些稍微的修改就行了;这里为了方便演示,且修都是改好了的,就直接贴出来了;

DiscardServer类:

@Component public class DiscardServer { @Resource private ChildChannelHandler childChannelHandler; public void run(int port) throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); System.out.println("准备运行端口:" + port); try { ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .option(ChannelOption.SO_BACKLOG, 128) .childHandler(childChannelHandler); //绑定端口,同步等待成功 ChannelFuture f = bootstrap.bind(port).sync(); //等待服务监听端口关闭 f.channel().closeFuture().sync(); } finally { //退出,释放线程资源 workerGroup.shutdownGracefully(); bossGroup.shutdownGracefully(); } } }

ChildChannelHandler类

@Component public class ChildChannelHandler extends ChannelInitializer<SocketChannel> { @Resource private DiscardServerHandler discardServerHandler; public void initChannel(SocketChannel socketChannel) throws Exception { socketChannel.pipeline().addLast(discardServerHandler); } }

3.DiscardServerHandler类

特别注意DiscardServerHandler类上需要加@Sharable注解,如果不加的话会报错;

@Component @Sharable public class DiscardServerHandler extends ChannelHandlerAdapter { @Resource private BaseService baseService; @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { try { ByteBuf in = (ByteBuf) msg; System.out.println("传输内容是"); System.out.println(in.toString(CharsetUtil.UTF_8)); //这里调用service服务 baseService.test(); } finally { ReferenceCountUtil.release(msg); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { // 出现异常就关闭 cause.printStackTrace(); ctx.close(); } }

3.netty调用所需的服务类

1.BaseService接口

public interface BaseService { /** * 测试接口 */ void test(); }

2.接口实现类BaseServiceImpl:

@Service public class BaseServiceImpl implements BaseService { @Override public void test() { System.out.println("调用service服务"); } }

4 springboot启动类

由于main方法是静态方法,netty服务启动类不是静态类,在main方法里面需要用new的方式启动;

也可以将netty服务启动类改为静态类,然后调用其他非静态的类时就得用new方法来构造其他类了;

我也百度到了几篇文章说实现CommandLineRunner接口,所以我用了springboot启动类实现CommandLineRunner接口的run方法,然后在run方法里启动netty服务

@SpringBootApplication public class DemoApplication implements CommandLineRunner { @Resource private DiscardServer discardServer; public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } @Override public void run(String... args) throws Exception { discardServer.run(8080); } }

5.测试

写一个能发送数据的socket就可以了;

发送的数据为:

public static void main(String[] args){ try { Socket socket=new Socket("localhost",8080); OutputStream outputStream = socket.getOutputStream(); PrintWriter printWriter=new PrintWriter(outputStream); printWriter.write("$tmb00035ET3318/08/22 11:5804029.94,027.25,20.00,20.00$"); printWriter.flush(); socket.shutdownOutput(); socket.close(); } catch (IOException e) { e.printStackTrace(); } }

我的测试结果:

传输内容是 $tmb00035ET3318/08/22 11:5804029.94,027.25,20.00,20.00$ aaaaa

到这里,netty与springboot的整合就完成了;

我在整合过程中遇到的问题

我使用springboot结合netty的流程

springboot启动类中启动netty启动类(DiscardServer),netty启动类(DiscardServer)再调用初始化channel类(ChildChannelHandler),然后初始化channel类再调用(DiscardServerHandler)类;然后DiscardServerHandler类再调用service服务;如下示例图:

问题:

  • springboot启动类我并没有实现CommandLineRunner接口,直接在main方法通过new的方式启动netty服务
  • 我实现了CommandLineRunner接口,但是我在run方法中用的new的方式启动的netty服务或者我在run方法使用注入的方式启动netty,但是在其他某个地方调用另一个类使用了new的方式;
  • DiscardServerHandler类上为标记@Sharable类,会报错误;

以上总结起来的问题就是我在springboot整合netty的过程中有其中一处的调用其他类时使用的方式是new构造的,这样虽然springboot能启动,netty也能启动,但是netty服务中使用new构造的那个类中无法依赖注入,会报空指针异常;

举个栗子:在图中的过程中,我在ChildChannelHandler类中通过new的方式调用DiscardServerHandler类,其他的过程都是使用注入的方式调用,就会出现上边的问题;

在遇到空指针的时候,我把spring托管的bean打印了出来,所有的类都在spring的托管中,但是就是无法注入,我也一直没有明白怎么回事,最后用了一个极端的方法,就是在调用服务时,获取spring的上下文,然后再根据名字来获取bean,你谷歌或百度:非托管类调用spring托管类,就能找到很多文章了;虽然用这个方式能解决上述的问题,但总是不好的;

最后的解决办法:所以类之间的调用都使用spring的依赖注入,别用new的方式来调用或者静态方法的方式调用

总结

既然项目中用到了spring,那么类与类之间的调用就用依赖注入,不然会报空指针的问题(就是非托管对象调用spring托管对象);这也算是一个常识性的问题了,只是自己现在才遇到这样的问题,还是要踩坑才能遇涨记性啊;这些问题困扰了我两三天,还是要有经验的人带,如果有经验的人带的话,说不几分钟就搞定了;

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持易盾网络。

本文共计1857个文字,预计阅读时间需要8分钟。

SpringBoot如何详细整合Netty开发步骤解析?

本文主要介绍了Spring Boot与Netty整合过程,详细解析了通过示例代码介绍的内容。对有一定学习或工作经验的读者来说,具有一定的参考价值。需要的朋友可以参考下文。

前言:上篇讲解了Netty的一个入门。

一、Spring Boot与Netty整合

1. 引言

随着微服务架构的普及,高性能、高并发的网络编程需求日益增长。Netty作为一款高性能的NIO框架,在处理高并发、低延迟的场景中有着出色的表现。而Spring Boot则是一个便捷的Java开发框架,可以将Netty整合到Spring Boot项目中,实现更高效的网络编程。

2. 整合步骤

(1)添加依赖

在Spring Boot项目中,首先需要在pom.xml文件中添加Netty和Spring Boot的依赖。

xml io.netty netty-all 4.1.42.Final org.springframework.boot spring-boot-starter

(2)创建NettyServer

在Spring Boot项目中创建一个NettyServer类,继承自SpringBootServletInitializer,实现ServletContainerInitializer接口。

javapublic class NettyServer extends SpringBootServletInitializer implements ServletContainerInitializer { @Override public void onStartup(ServletContext servletContext) throws ServletException { // 创建Netty服务器 EventLoopGroup bossGroup=new NioEventLoopGroup(); EventLoopGroup workerGroup=new NioEventLoopGroup(); try { ServerBootstrap b=new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer() { @Override protected void initChannel(SocketChannel ch) throws Exception { // 添加处理器 ch.pipeline().addLast(new NettyServerHandler()); } }) .option(ChannelOption.SO_BACKLOG, 128) .childOption(ChannelOption.SO_KEEPALIVE, true);

// 绑定端口并启动服务器 ChannelFuture f=b.bind(8080).sync(); // 等待服务器socket关闭 f.channel().closeFuture().sync(); } finally { workerGroup.shutdownGracefully(); bossGroup.shutdownGracefully(); } }}

(3)创建NettyServerHandler

在NettyServer类中创建NettyServerHandler类,继承自ChannelInboundHandlerAdapter,实现业务逻辑处理。

javapublic class NettyServerHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { // 业务处理 System.out.println(Received message: + msg); // 回复客户端 ctx.writeAndFlush(Received your message.); }}

(4)启动Spring Boot项目

SpringBoot如何详细整合Netty开发步骤解析?

通过以上步骤,Netty与Spring Boot项目成功整合。在启动Spring Boot项目后,Netty服务器将在8080端口监听。

3. 总结

本文详细介绍了Spring Boot与Netty的整合过程,通过示例代码展示了如何实现Netty服务器。对于有网络编程需求的读者,可以参考本文进行实践。

这篇文章主要介绍了springboot整合netty过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

前言

上一篇讲了netty的一个入门的demo;项目上我也把数据处理做好了,就要开始存数据库了;我用的mybatis框架,如果单独使用还是觉得比较麻烦,所以就用了springboot+mybatis+netty;本篇主要讲netty与springboot的整合,以及我在这个过程中遇到的问题,又是怎么去解决的;

正文

我在做springboot与netty整合的时候在谷歌,百度找了无数文章,都没有一篇是自己想要的,也达不到自己所想的目的;

代码

1. 新建一个springboot项目,在pom文件中添加netty依赖:

<dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>5.0.0.Alpha1</version> </dependency>

2.新建netty服务
其实可以复制上一篇文章的netty的三个服务类,做一些稍微的修改就行了;这里为了方便演示,且修都是改好了的,就直接贴出来了;

DiscardServer类:

@Component public class DiscardServer { @Resource private ChildChannelHandler childChannelHandler; public void run(int port) throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); System.out.println("准备运行端口:" + port); try { ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .option(ChannelOption.SO_BACKLOG, 128) .childHandler(childChannelHandler); //绑定端口,同步等待成功 ChannelFuture f = bootstrap.bind(port).sync(); //等待服务监听端口关闭 f.channel().closeFuture().sync(); } finally { //退出,释放线程资源 workerGroup.shutdownGracefully(); bossGroup.shutdownGracefully(); } } }

ChildChannelHandler类

@Component public class ChildChannelHandler extends ChannelInitializer<SocketChannel> { @Resource private DiscardServerHandler discardServerHandler; public void initChannel(SocketChannel socketChannel) throws Exception { socketChannel.pipeline().addLast(discardServerHandler); } }

3.DiscardServerHandler类

特别注意DiscardServerHandler类上需要加@Sharable注解,如果不加的话会报错;

@Component @Sharable public class DiscardServerHandler extends ChannelHandlerAdapter { @Resource private BaseService baseService; @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { try { ByteBuf in = (ByteBuf) msg; System.out.println("传输内容是"); System.out.println(in.toString(CharsetUtil.UTF_8)); //这里调用service服务 baseService.test(); } finally { ReferenceCountUtil.release(msg); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { // 出现异常就关闭 cause.printStackTrace(); ctx.close(); } }

3.netty调用所需的服务类

1.BaseService接口

public interface BaseService { /** * 测试接口 */ void test(); }

2.接口实现类BaseServiceImpl:

@Service public class BaseServiceImpl implements BaseService { @Override public void test() { System.out.println("调用service服务"); } }

4 springboot启动类

由于main方法是静态方法,netty服务启动类不是静态类,在main方法里面需要用new的方式启动;

也可以将netty服务启动类改为静态类,然后调用其他非静态的类时就得用new方法来构造其他类了;

我也百度到了几篇文章说实现CommandLineRunner接口,所以我用了springboot启动类实现CommandLineRunner接口的run方法,然后在run方法里启动netty服务

@SpringBootApplication public class DemoApplication implements CommandLineRunner { @Resource private DiscardServer discardServer; public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } @Override public void run(String... args) throws Exception { discardServer.run(8080); } }

5.测试

写一个能发送数据的socket就可以了;

发送的数据为:

public static void main(String[] args){ try { Socket socket=new Socket("localhost",8080); OutputStream outputStream = socket.getOutputStream(); PrintWriter printWriter=new PrintWriter(outputStream); printWriter.write("$tmb00035ET3318/08/22 11:5804029.94,027.25,20.00,20.00$"); printWriter.flush(); socket.shutdownOutput(); socket.close(); } catch (IOException e) { e.printStackTrace(); } }

我的测试结果:

传输内容是 $tmb00035ET3318/08/22 11:5804029.94,027.25,20.00,20.00$ aaaaa

到这里,netty与springboot的整合就完成了;

我在整合过程中遇到的问题

我使用springboot结合netty的流程

springboot启动类中启动netty启动类(DiscardServer),netty启动类(DiscardServer)再调用初始化channel类(ChildChannelHandler),然后初始化channel类再调用(DiscardServerHandler)类;然后DiscardServerHandler类再调用service服务;如下示例图:

问题:

  • springboot启动类我并没有实现CommandLineRunner接口,直接在main方法通过new的方式启动netty服务
  • 我实现了CommandLineRunner接口,但是我在run方法中用的new的方式启动的netty服务或者我在run方法使用注入的方式启动netty,但是在其他某个地方调用另一个类使用了new的方式;
  • DiscardServerHandler类上为标记@Sharable类,会报错误;

以上总结起来的问题就是我在springboot整合netty的过程中有其中一处的调用其他类时使用的方式是new构造的,这样虽然springboot能启动,netty也能启动,但是netty服务中使用new构造的那个类中无法依赖注入,会报空指针异常;

举个栗子:在图中的过程中,我在ChildChannelHandler类中通过new的方式调用DiscardServerHandler类,其他的过程都是使用注入的方式调用,就会出现上边的问题;

在遇到空指针的时候,我把spring托管的bean打印了出来,所有的类都在spring的托管中,但是就是无法注入,我也一直没有明白怎么回事,最后用了一个极端的方法,就是在调用服务时,获取spring的上下文,然后再根据名字来获取bean,你谷歌或百度:非托管类调用spring托管类,就能找到很多文章了;虽然用这个方式能解决上述的问题,但总是不好的;

最后的解决办法:所以类之间的调用都使用spring的依赖注入,别用new的方式来调用或者静态方法的方式调用

总结

既然项目中用到了spring,那么类与类之间的调用就用依赖注入,不然会报空指针的问题(就是非托管对象调用spring托管对象);这也算是一个常识性的问题了,只是自己现在才遇到这样的问题,还是要踩坑才能遇涨记性啊;这些问题困扰了我两三天,还是要有经验的人带,如果有经验的人带的话,说不几分钟就搞定了;

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持易盾网络。