SpringBoot集成Netty时在Handler类中注入Bean为null解决方案

问题由来?

这几天自己想捣鼓一个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 {
    @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 {
    @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类中注入Bean为null解决方案)