SpringBoot整合Netty

需要实现下面几点

1.spring中启动netty

2.在netty中使用spring中管理的bean,spring的功能

3.netty需要使用spirng中bean处理外部的请求,所以netty的启动必须在spring完整启动后

首先Main类
1 public class Main {
2 
3     public static void main(String[] args) {
4         SpringApplication.run(ApplicationConfig.class, args);
5     }
6 }

在spring完整启动后再创建netty,开始监听端口,这个需求和spingboot自己的Tomcat启动类似

先看下tomcat在什么地方启动

1     @Override
2     protected void finishRefresh() {
3         super.finishRefresh();
4         WebServer webServer = startWebServer();
5         if (webServer != null) {
6             publishEvent(new ServletWebServerInitializedEvent(webServer, this));
7         }
8     }

调用栈

AnnotationConfigServletWebServerApplicationContext(ServletWebServerApplicationContext).finishRefresh() line: 164    
    AnnotationConfigServletWebServerApplicationContext(AbstractApplicationContext).refresh() line: 552    
    AnnotationConfigServletWebServerApplicationContext(ServletWebServerApplicationContext).refresh() line: 142    
    SpringApplication.refresh(ApplicationContext) line: 775    
    SpringApplication.refreshContext(ConfigurableApplicationContext) line: 397    
    SpringApplication.run(String...) line: 316    
    SpringApplication.run(Class<?>[], String[]) line: 1260    
    SpringApplication.run(Class<?>, String...) line: 1248    
    Main.main(String[]) line: 9    

可以看到tomcat是在finishRefresh之后才启动的,这时候spring已经做完了所有bean的处理,

但是好像没有给我们预留自定义的处理接口

1 refreshContext(context);
2 afterRefresh(context, applicationArguments);
3 stopWatch.stop();
4 if (this.logStartupInfo) {
5     new StartupInfoLogger(this.mainApplicationClass)
6                         .logStarted(getApplicationLog(), stopWatch);
7 }
8 listeners.started(context);
9 callRunners(context, applicationArguments);

向外层寻找发现了一个callRunners,并且支持自定义

综上,想要在Spring完整启动后,再开启Netty监听端口,最好的方法应该是实现ApplicationRunner

 1     private EventLoopGroup bossGroup;
 2     private EventLoopGroup workerGroup;
 3     
 4     @Override
 5     public void run(ApplicationArguments args) throws Exception {
 6         new Thread(this::startNetty, "NettyServer").start();
 7     }
 8     
 9     private void startNetty() {
10         int port = 7788;
11         logger.error("Netty Server Starting...");
12         bossGroup = new NioEventLoopGroup();
13         workerGroup = new NioEventLoopGroup();
14         try {
15             ServerBootstrap b = new ServerBootstrap();
16             b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
17                     .option(ChannelOption.SO_BACKLOG, 1024)
18                     .childHandler(new ChannelInitializer<SocketChannel>() {
19                         @Override
20                         protected void initChannel(SocketChannel socketChannel) throws Exception {
21                             socketChannel.pipeline().addLast(new IdleStateHandler(5, 5, 5, TimeUnit.SECONDS));
22                             socketChannel.pipeline().addLast(new TimeServerHandler());
23                         }
24                     });
25 
26             ChannelFuture f = b.bind(port).sync();
27             logger.error("Netty server build port:" + port);
28             
29             f.channel().closeFuture().sync();
30         } catch (Exception e) {
31             e.printStackTrace();
32         } finally {
33             workerGroup.shutdownGracefully();
34             bossGroup.shutdownGracefully();
35         }
36         logger.error("Netty Server Shutdown completed");
37     }

 

上一篇:spring boot kafak 配置


下一篇:Spring boot java.lang.NoClassDefFoundError: org/springframework/boot/bind/RelaxedPropertyResolver