我有Spring和Netty的申请。问题是我正在尝试以使Netty的处理程序对于每个渠道都是唯一的方式集成这两个框架。

因此,初始化Netty服务器的组件如下所示:

@Component
public class TCPServer {

...

@Autowired
@Qualifier("messageHandler")
private MessageHandler messageHandler;

private Channel serverChannel;

public void start() throws Exception {
    logger.info("Starting TCP Server...");
    ServerBootstrap b = new ServerBootstrap();
    final EventExecutorGroup customGroup = new DefaultEventExecutorGroup(100);

    b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
    .childHandler(new ChannelInitializer<SocketChannel>() {
        @Override
        protected void initChannel(SocketChannel channel) throws Exception {
            ChannelPipeline pipeline = channel.pipeline();
            pipeline.addLast(new Encoder());
            pipeline.addLast(new Decoder());
            pipeline.addLast(customGroup, messageHandler);
        }
    });
    Set<ChannelOption<?>> keySet = tcpChannelOptions.keySet();
    for (@SuppressWarnings("rawtypes") ChannelOption option : keySet) {
        b.option(option, tcpChannelOptions.get(option));
    }

    serverChannel =  b.bind(tcpPort).sync().channel();
    logger.info("TCP Server started.");
}
...
}


和处理程序:

@Component
@Sharable
public class MessageHandler extends SimpleChannelInboundHandler<Message> {

@Autowired
private ChannelRepository channelRepository;

private CommandUtil commandUtil;

@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {

    channelRepository.put(channelKey, ctx.channel());
    commandUtil = new CommandUtil();
    ctx.channel().attr(AttributeKey.valueOf("commands")).set(commandUtil);

}
...
}


这可以正常工作,但是问题是Netty仅创建MessageHandler类的一个实例,并且如果我替换注入的MessageHandler并在每次(new MessageHandler())放置新实例时都丢失Spring上下文-channelRepository为null。

问题是如何为每个通道实现MessageHandler的新实例,而又不丢失Spring上下文(使用自动装配字段)?

最佳答案

为您的MessageHandler创建一个Factory。将ChannelRepository注入您的工厂,并将工厂注入ChannelInitializer(TCPServer)。

从MessageHandler中删除@Sharable,这可以防止您意外地在多个通道中使用同一文件夹。仅在安全跨通道共享同一处理程序的情况下,才应添加此注释。

09-27 02:55