2

我写了以下内容,但它立即退出:

public static void main(String[] args) {
    new ClassPathXmlApplicationContext("/springtests/test01.xml");
}

test01.xml包含多个带有一些线程(守护进程)的 bean,这些线程(守护进程)连接到网络等。

怎么等?

4

6 回答 6

4

您所做的只是在这里创建一个对象。您需要检索 bean,然后使用它们。例如

ApplicationContext ctx = new ClassPathXmlApplicationContext("/springtests/test01.xml");
MyClass myObj= MyClass.class.cast(ctx.getBean("myBeanName"));         
myObj.doStuff();

如果您需要更多帮助,请发布 test01.xml 中的内容

于 2012-09-26T18:09:20.050 回答
1

尽管我同意其他答案中的大多数建议,但我认为您的主要方法是可以的。您唯一需要更改的是至少使您的一个工作线程成为非守护程序。

来自 Thread.setDaemon Java 文档:

当唯一运行的线程都是守护线程时,Java 虚拟机退出。

还要确保在 bean 的 init 方法(或 afterPropertiesSet)期间启动所有线程,并且不需要启动 bean(实现生命周期接口)。您对所有 bean 进行编码的方式将被初始化但不会启动。

于 2012-09-26T18:20:12.083 回答
1

怎么等?

我使用了类似以下模式的东西。我的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();
    }
}
于 2012-09-26T19:23:05.313 回答
0

你可以调用context.registerShutdownHook()确保applicationContext中的beans被正确关闭,但是如果applicationContext只启动守护线程,你仍然需要确保主线程不退出。

一个更好的策略是main()从它可以调用的上下文中检索一些 bean bean.startApp(),以启动事情 - 或者至少有一个在上下文中启动的线程是非守护程序的。

于 2012-09-26T18:09:28.623 回答
0

你可以让你的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));
    }
}
于 2014-11-05T13:23:22.250 回答
0

初始化弹簧上下文后,请在单独的线程中执行逻辑。随着新线程的启动,可以等待一个条件,主线程将完成,而您的逻辑仍在另一个线程中运行。该线程可以通过 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();
}
                            }
        })
于 2016-10-11T23:45:15.290 回答