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
注释或手动结束相应的工作单元(如上例所示)。
我正在使用 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
注释或手动结束相应的工作单元(如上例所示)。