0

我已将 Neo4j 连接添加到一个简单的 Spring Boot 命令行应用程序——它实现了CommandLineRunner.

我几乎遵循了Neo4j 驱动程序手册中的示例,但我的应用程序在完成后不会终止main()
与这些来源的唯一偏差是该driver.close()方法不是在main()最后调用,而是在一个带@PreDestroy注释的方法中:

@Service
public class DatabaseGraphService {
    
    private volatile Driver driver;
    
    private final Logger LOG;
    
    public DatabaseGraphService() {
        LOG = LogManager.getLogger(getClass());
    }

    @PostConstruct
    private void initialize() throws Exception {
        driver = GraphDatabase.driver("bolt://localhost:7687", AuthTokens.basic("neo4j", "neo4j"));
    }
    
    @PreDestroy
    public void close() throws Exception {
        LOG.info("Shutting down Neo4j driver...");
        driver.close();
    }
    
    // ...
    
}

主类:

@SpringBootApplication(scanBasePackages={ "it" })
public class SpringBootConsoleApplication implements CommandLineRunner {

    @Autowired
    private DatabaseGraphService graphService;
    
    private static Logger LOG = LoggerFactory
      .getLogger(SpringBootConsoleApplication.class);

    public static void main(String[] args) {
        LOG.info("STARTING THE APPLICATION");
        
        SpringApplication.run(SpringBootConsoleApplication.class, args);
        LOG.info("APPLICATION FINISHED");
    }
 
    @Override
    public void run(String... args) {
        LOG.info("EXECUTING : command line runner");
    }
    
}

我在 Sprint Tools Suite(基于 Eclipse 的 IDE)中运行它,它记录的内容如下:

i.c.c.e.SpringBootConsoleApplication     : APPLICATION FINISHED

但仅此而已,该过程保持活跃;当我按下停止按钮时,然后:

inMXBeanRegistrar$SpringApplicationAdmin : Application shutdown requested.
i.c.c.services.DatabaseGraphService      : Shutting down Neo4j driver...
com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
[...]

如果我在不执行任何查询的情况下运行程序,则该过程定期存在。只要我进行查询——无论我是使用所有结果还是对Result对象不做任何事情——它都会保持活动状态。

难道我做错了什么?或者这可能是预期的行为,因为当main()完成时它只是它的线程终止?

虽然,在同一个应用程序中,我连接到一个 PostgreSQL 实例,也在那里进行查询,但是在添加 Neo4j 连接之前应用程序正确终止。

4

1 回答 1

0

Neo4j Java Driver 管理负责网络通信的内部线程。它在涉及网络的第一次 API 使用时引导它们。

您的应用程序不会退出,因为这些线程一直在运行。要关闭它们,您必须调用 Driver 的 close 方法。4.3.4 Javadoc 片段:

Close all the resources assigned to this driver, including open connections and IO threads.

在所描述的设置中,它应该在运行打包的 JAR 时在中断信号 (CTRL+C) 上调用。

从版本 4.3.2 开始,这些线程已更新为守护线程,因此它们不会阻止应用程序完成执行。此外,此更改也已向后移植到版本 4.2.7 和 4.1.4。

于 2021-10-25T15:21:32.157 回答