美文网首页netty
SpringBoot集成Netty时在Handler类中注入Be

SpringBoot集成Netty时在Handler类中注入Be

作者: 马路边的小破孩 | 来源:发表于2020-08-05 10:28 被阅读0次

    问题由来?

    这几天自己想捣鼓一个im项目,springboot集成Netty来做服务端处理和转发消息,结果发现handler中使用@Autowired注入的bean全部为null,试图找出原因。

    为什么会出现注入bean全部为null?

    可能我们潜意识的认为,我们使用@Autowired注入的bean应该会有对应的实例化对象,因为全部是通过spring进行bean的创建管理和注入的。那是因为我们使用的spring的注解,但是Netty的handler是我们通过new 出来的对象,spring是管不到的,即无法注入bean;例外还有一点不同的是,spring默认创建的对像都是单例的,这种可能也不太适合netty。

    解决方式

    网上的几种方式(无论是实现ApplicationContextAware类通过获取bean还是将要注入的 service 改成 static,再通过set方法,或者是通过@PostConstruct注解init()初始化)获取的对像仍然全部为null,可能我的姿势不大对😀😃~~

    下面说说我的代码是怎么样的(要不然怎么会知道为什么我的姿势不对呢?☹️)

    注入bean为null时的代码

    springboot的启动类

    @SpringBootApplication
    public class ImSeverApplication {
        @Autowired
        private NettyBootstrap nettyBootstrap;
        public static void main(String[] args) {
            SpringApplication.run(ImSeverApplication.class, args);
        }
    
        @PostConstruct
        public void startNetty() {
            nettyBootstrap.setPort(8888).start();
        }
    
    }
    

    netty 的启动引导类

    @Slf4j
    @Component
    public class NettyBootstrap {
        private int port;
        public NettyBootstrap() {
        }
        public NettyBootstrap setPort(int port) {
            this.port = port;
            return this;
        }
        public void start() {
            NioEventLoopGroup boss = new NioEventLoopGroup();
            NioEventLoopGroup worker = new NioEventLoopGroup();
    
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(boss, worker)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitiallizer())
                    .option(ChannelOption.SO_BACKLOG, 1024)
                    .childOption(ChannelOption.SO_KEEPALIVE, true);
    
            try {
                ChannelFuture channelFuture = serverBootstrap.bind(port).sync();
                log.info("Netty Server Start Success");
                channelFuture.channel().closeFuture().sync();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                boss.shutdownGracefully();
                worker.shutdownGracefully();
            }
        }
    }
    

    ChannelInitiallizer 类

    public class ChannelInitiallizer extends ChannelInitializer<SocketChannel> {
        @Override
        protected void initChannel(SocketChannel socketChannel) throws Exception {
            socketChannel.pipeline()
                    .addLast("codec", new HttpServerCodec())
                    .addLast("chunked", new ChunkedWriteHandler())
                    .addLast("aggreator", new HttpObjectAggregator(65536))
                    .addLast(new WebSocketServerProtocolHandler("/ws/chat"))
                    .addLast(new BinaryWebSocketFrameHandler());
        }
    }
    

    BinaryWebSocketFrameHandler 类

    public class BinaryWebSocketFrameHandler extends SimpleChannelInboundHandler<BinaryWebSocketFrame> {
        @Autowired
        private RedisUtil redisUtil ;
        @Autowired
        private UserGroupService userGroupService ;
    
        @Override
        protected void channelRead0(ChannelHandlerContext channelHandlerContext, BinaryWebSocketFrame binaryWebSocketFrame){
    
    }
    }
    
    自己的解决方式(构造方式注入对象,红框内即为变动后的代码)
    image.png
    image.png
    image.png

    可能方法还是不那么尽人意,但还是解决了我的问题,希望能帮到~

    相关文章

      网友评论

        本文标题:SpringBoot集成Netty时在Handler类中注入Be

        本文链接:https://www.haomeiwen.com/subject/dkysrktx.html