【问题标题】:Spring and NettySpring 和 Netty
【发布时间】:2017-03-27 07:35:26
【问题描述】:

我有 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为空。

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

【问题讨论】:

    标签: java netty


    【解决方案1】:

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

    从 MessageHandler 中删除 @Shareable,这将防止您在多个频道中意外使用同一个。只有在跨通道共享同一个处理程序是安全的情况下,您才应该添加此注释。

    【讨论】:

    • 我如何在MassageHandler 中访问ChannelRepository
    • 给MessageHandler添加一个构造函数,并从工厂传入到正在创建的实例中
    猜你喜欢
    • 2019-03-18
    • 2022-12-22
    • 2021-08-01
    • 2017-08-04
    • 1970-01-01
    • 1970-01-01
    • 2021-05-16
    • 2020-06-03
    • 2020-11-20
    相关资源
    最近更新 更多