我写了以下内容,但它立即退出:
public static void main(String[] args) {
new ClassPathXmlApplicationContext("/springtests/test01.xml");
}
test01.xml
包含多个带有一些线程(守护进程)的 bean,这些线程(守护进程)连接到网络等。
怎么等?
您所做的只是在这里创建一个对象。您需要检索 bean,然后使用它们。例如
ApplicationContext ctx = new ClassPathXmlApplicationContext("/springtests/test01.xml");
MyClass myObj= MyClass.class.cast(ctx.getBean("myBeanName"));
myObj.doStuff();
如果您需要更多帮助,请发布 test01.xml 中的内容
尽管我同意其他答案中的大多数建议,但我认为您的主要方法是可以的。您唯一需要更改的是至少使您的一个工作线程成为非守护程序。
来自 Thread.setDaemon Java 文档:
当唯一运行的线程都是守护线程时,Java 虚拟机退出。
还要确保在 bean 的 init 方法(或 afterPropertiesSet)期间启动所有线程,并且不需要启动 bean(实现生命周期接口)。您对所有 bean 进行编码的方式将被初始化但不会启动。
怎么等?
我使用了类似以下模式的东西。我的Main
线程启动上下文,然后等待其他人调用Main.shutdownLatch.countDown()
命令告诉它关闭上下文并退出。我通常使用 JMX 命令来执行此操作。
public static CountDownLatch shutdownLatch = new CountDownLatch(1);
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("/springtests/test01.xml");
try {
shutdownLatch.await();
} finally {
context.close();
}
}
你可以调用context.registerShutdownHook()
确保applicationContext中的beans被正确关闭,但是如果applicationContext只启动守护线程,你仍然需要确保主线程不退出。
一个更好的策略是main()
从它可以调用的上下文中检索一些 bean bean.startApp()
,以启动事情 - 或者至少有一个在上下文中启动的线程是非守护程序的。
你可以让你的bean实现,ApplicationListener<ContextStartedEvent>
即:
@Override
public final void onApplicationEvent(ContextStartedEvent event) {...
也许还有ExitCodeGenerator
:
@Override
public int getExitCode() {
那么你的主要方法可能是:
public static void main(String[] args) {
try (ConfigurableApplicationContext context = SpringApplication.run(AppConfig.class, args)) {
context.start();
System.exit(SpringApplication.exit(context));
}
}
初始化弹簧上下文后,请在单独的线程中执行逻辑。随着新线程的启动,可以等待一个条件,主线程将完成,而您的逻辑仍在另一个线程中运行。该线程可以通过 JMX 更新变量值来停止。
ApplicationContext ctx = new ClassPathXmlApplicationContext("/springtests/test01.xml");
MyClass myObj= MyClass.class.cast(ctx.getBean("myBeanName"));
ExecutorService executor= Executors.newSingleThreadExecutor();
executor.submit(new Runnable() {
@Override
public void run() {
//Update the value of this variable via jmx
while(<SomeAtomicBooleanValueCheck>)
{
myObj.doStuff();
}
}
})