在基于 Netty 的应用程序中进行单元测试后,SpringApplication 未关闭

SpringApplication is not closing after unit test in a Netty based application

我有一个 "springified" 的 Netty 服务。服务 运行 正常并处理 requests/responses。

我没有添加 unit-tests/integration 测试。我看到 spring 上下文在测试后没有关闭。即 netty 服务器在测试完成后 运行ning。我可以 telnet 到端口并看到它仍然连接到它

这是我的 SpringBootApp 文件

@SpringBootApplication
public class NettyService {

    //Autowired all the required fields

    //I made this static so I can access from integration tests to shut it down. I shouldn't need
    //this since after each test jvm should be shut-down.
    static ChannelFuture serverChannelFuture;

    public static void main( String[] args ) {
        SpringApplication.run(NettyService.class, args);

    }

    @PostConstruct
    public void start() throws InterruptedException {
        serverChannelFuture = bootstrap.bind(tcpSocketAddress).sync();
    }

    @PreDestroy
    public void stop() throws InterruptedException {
        serverChannelFuture.channel().closeFuture().sync();
    }

}

测试class

@RunWith(SpringRunner.class)
@SpringBootTest(classes=NettyService.class)
public class AppTest
{

    @After
    public void cleanUp() throws Exception {
        //NettyService.serverChannelFuture.channel().closeFuture().sync();
    }


    @Test
    public void contextLoad1() throws Exception
    {
        assertTrue( true );
    }

    @Test
    public void contextLoad2() throws Exception
    {
        assertTrue( true );
    }

第一次测试时,顺利通过。但第二次测试失败并出现 "Address in use" 错误。 第一次测试完成后,Netty 并没有拆除。我希望 spring 上下文在测试结束时关闭或至少 jvm 退出。

注意,我已经注释掉了 cleanUp() 方法中的行。如果我取消注释,即使是第一个测试也不是 运行。它只是永远挂着。

您错误地关闭了 Netty。

@PreDestroy
public void stop() throws InterruptedException {
    serverChannelFuture.channel().closeFuture().sync();
}

这只是在等待服务器通道关闭,但从未请求它实际关闭,这将永远阻塞。

而不是调用 .closeFuture()(将来的事件),调用 .close()(现在关闭它)。

@PreDestroy
public void stop() throws InterruptedException {
    serverChannelFuture.channel().close().sync();
}

如果您还使用 NioEventLoopGoup 的新实例创建线程池,请确保在关闭通道后通过调用其关闭函数来终止线程池。