Guice Injector 保留应用程序 运行

Guice Injector keeps application running

我正在使用 guice 来注入我的依赖项。我的 IDE 是 IntelliJ 2017.2.5。当我 运行 以下代码时,我的 main 方法保持 运行ning 并且不会停止。当我删除 DI 时,进程以 Process finished with exit code 0.

停止

class与main方法:

public class Test {

@Inject
Provider<EntityManager> em;

public void test() {
    if(em.get().isOpen())
        System.out.println("EM open");
}

public static void main(String args[]) {
    final Injector injector = createInjector(new DatabaseModule());
    Test app = injector.getInstance(Test.class);
    app.test();
    System.out.println("Done");
}
}

DatabaseModule:

public class DatabaseModule extends AbstractModule {

private static final String PU_NAME = "my_pu";

@Override
protected void configure() {
    install(new JpaPersistModule(PU_NAME));
    bind(JPAInitializer.class).asEagerSingleton();
}

@Singleton
private static class JPAInitializer {
    @Inject
    public JPAInitializer(final PersistService service) {
        service.start();
    }
}

}

如果我执行 Test.main 一切顺利,JPA 已正确初始化并且我看到以下输出:

EM open
Done

出于某种原因,应用程序在那之后仍然 运行ning。我必须手动终止应用程序。

我该如何解决这个问题?

您可能有一些打开的数据库 connections/threads 等待明确关闭 由于您使用的是 Hibernate,因此请确保在最后关闭 () SessionFactory(如果您正在使用它)

在 IntelliJ 中,您可以获取线程转储以查看哪些线程仍running/waiting 被关闭

检查一下你错过了什么

您没有释放获取的资源(数据库连接和非守护线程)。

public class Test {

  @Inject
  Provider<EntityManager> em;

  @Inject
  UnitOfWork unitOfWork;

  public void test() {
    if(em.get().isOpen())
        System.out.println("EM open");
    unitOfWork.end();  // releases DB connection
  }

  public static void main(String args[]) {
    final Injector injector = createInjector(new DatabaseModule());
    Test app = injector.getInstance(Test.class);
    app.test();
    System.out.println("Done");
    injector.get(PersistService.class).stop();  // releases resources acquired by the underlying EntityManagerFactory
  }
}

从技术上讲,在这种情况下只需停止 PersistService 就足够了,但通常您应该在不再需要 EntityManager 时将其关闭。您应该使用 Guice JPA 执行此操作的方法是使用 @Transactional 注释或手动结束相应的工作单元(如上例所示)。