Spring 和 Netty
Spring and Netty
我有 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
class 的实例,如果我每次替换注入的 MessageHandler
并放置新实例(new MessageHandler()
) 我失去了 Spring 上下文 - channelRepository
为空。
问题是我如何为每个通道实现 MessageHandler 的新实例而不丢失 Spring 上下文(使用自动装配字段)?
为您的 MessageHandler 创建工厂。将 ChannelRepository 注入您的工厂,并将工厂注入您的 ChannelInitializer (TCPServer)。
从 MessageHandler 中删除@Sharable,这将防止您在多个通道中意外使用同一个。只有在跨渠道共享同一个处理程序是安全的情况下,您才应该添加此注释。
我有 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
class 的实例,如果我每次替换注入的 MessageHandler
并放置新实例(new MessageHandler()
) 我失去了 Spring 上下文 - channelRepository
为空。
问题是我如何为每个通道实现 MessageHandler 的新实例而不丢失 Spring 上下文(使用自动装配字段)?
为您的 MessageHandler 创建工厂。将 ChannelRepository 注入您的工厂,并将工厂注入您的 ChannelInitializer (TCPServer)。
从 MessageHandler 中删除@Sharable,这将防止您在多个通道中意外使用同一个。只有在跨渠道共享同一个处理程序是安全的情况下,您才应该添加此注释。