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     }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM